Sass makes CSS fun!

Overview

Sass

@SassCSS on Twitter    stackoverflow    Gitter

Sass makes CSS fun again. Sass is an extension of CSS, adding nested rules, variables, mixins, selector inheritance, and more. It's translated to well-formatted, standard CSS using the command line tool or a plugin for your build system.

$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}

@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
     -moz-border-radius: $radius;
      -ms-border-radius: $radius;
          border-radius: $radius;
}

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { @include border-radius(10px); }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

Install Sass

You can install Sass on Windows, Mac, or Linux by downloading the package for your operating system from GitHub and adding it to your PATH. That's all—there are no external dependencies and nothing else you need to install.

If you use Node.js, you can also install Sass using npm by running

npm install -g sass

However, please note that this will install the pure JavaScript implementation of Sass, which runs somewhat slower than the other options listed here. But it has the same interface, so it'll be easy to swap in another implementation later if you need a bit more speed!

See the Sass website for more ways to install Sass.

Once you have Sass installed, you can run the sass executable to compile .sass and .scss files to .css files. For example:

sass source/stylesheets/index.scss build/stylesheets/index.css

Learn Sass

Check out the Sass website for a guide on how to learn Sass!

This Repository

This repository isn't an implementation of Sass. Those live in sass/dart-sass and sass/libsass. Instead, it contains:

  • spec/, which contains specifications for language features.
  • proposal/, which contains in-progress proposals for changes to the language.
  • accepted/, which contains proposals that have been accepted and are either implemented or in the process of being implemented.

Note that this doesn't contain a full specification of Sass. Instead, feature specifications are written as needed when a new feature is being designed or when an implementor needs additional clarity about how something is supposed to work. This means many of the specs in spec/ only cover small portions of the features in question.

Versioning Policy

The proposals in this repository are versioned, to make it easy to track changes over time and to refer to older versions. Every version has a Git tag of the form proposal.<name>.draft-<version>. A new version should be created for each batch of changes.

Every version has a major version, and they may have a minor version as well (indicated <major>.<minor>). The minor version should be incremented for changes that don't affect the intended semantics of the proposal; otherwise, the major version should be incremented.

Comments
  • Importing CSS as Sass files

    Importing CSS as Sass files

    (edited by @nex3)


    I've recently wanted to start including .css files and have them parsed as Sass. The idea behind this is that a component might be added to the project as a third-party component and I'll want to import their CSS for use in Sass.

    This would allow us to have project in Bower (and other package managers) for reusable CSS components that would work with or without Sass. Take the Normalize.css file for example, I would like to be able to add this to a project using Bower and import it into the project as I would an SCSS file rather than creating a vanilla CSS import.

    I imagine this would mean letting this syntax:

    @import "normalize"
    

    look for normalize.sass, normalise.scss or normalize.css and pull it in. Currently it will ignore it if it only finds a css file.

    Would there be any downsides to this?

    /cc @chriseppstein

    enhancement specs written 
    opened by anthonyshort 126
  • Passing arguments from a mixin to a content block

    Passing arguments from a mixin to a content block


    Mixin content is great and has done wonders for code implementing wrapper and context abstractions. However, there is often some setup done in the mixin and that setup needs to be available to the content when it is included. The current strategy is to use global variables, which works, but is obviously not ideal.

    I'd like to introduce a way for mixins to include their content block and to pass arguments to the content.

    Calling the content with arguments

    In order to pass arguments to content blocks an argument list can be passed to the content directive. This accepts positional and keyword arguments for passing to a content block. Variable argument semantics are allowed.

    @mixin accepts-content {
      @for $i from 1 to 5 {
        @content ($i, 360deg * $i / 5);
      }
    }
    

    Receiving arguments within a content block

    A content block receives arguments using a new directive called @receive. The directive allows an argument list declaration that is the same as for functions and mixins. Positional arguments, default values, and variable arguments are all allowed.

    @include accepts-content {
      @receive ($number, $hue);
      .color-#{$number} {
        background-color: hsl($hue, 75%, 90%);
      }
    }
    
    enhancement specs written 
    opened by chriseppstein 124
  • [feature request] More intelligent compression

    [feature request] More intelligent compression

    It would be great if SASS output could be configured to more intelligently compress output. Here are some examples:

    # Combine name-spaced selectors
    # SASS                             # Preferred Output                 # Current Output
    body {                             body{border:3px solid #ccc;}       body{border-width:3px;border-color:#ccc;border-style:solid;}
      border: {
        width: 3px;
        color: #ccc;
        style: solid
        }
    }
    
    # Combine multiple declarations
    # SASS                             # Preferred Output                 # Current Output
    body { border: solid #ccc; }       body{border:3px solid #ccc;}       body{border:solid #ccc;}
    body { border-width: 3px; }                                           body{border-width:3px;}
    
    # SASS                             # Preferred Output                 # Current Output
    body { color: #ccc; }              body{color:#ccc;cursor:pointer;}   body{color:#ccc;}
    body { cursor: pointer; }                                             body{cursor:pointer;}          
    
    # Ignore overridden declarations
    # SASS                             # Preferred Output                 # Current Output
    body { border: 2px solid #400; }   body{border:3px solid #ccc;}       body{border:2px solid #400;}
    body { border: 3px solid #ccc; }                                      body{border:3px solid #ccc;}
    

    This would allow you to more expressively organise stylesheets and partials without sacrificing on output length. For example, you could have color, typography and layout partials which, when compiled, gave the same output as if they had been written all mixed together.

    There maybe gotchas with doing this due to the cascading nature of stylesheets and this effectively changes the ordering of declarations. However, I can't immediately think of specifics and the first case at least does not seem to be problematic.

    This should also only apply when the compressed output option has been set as the readability of stylesheets may be impacted. For example, in development, it might be useful for the output to indicate that the designer has intended to split declarations in a particular way.

    enhancement 
    opened by rupert-madden-abbott 111
  • Add a flag to emit ASCII-only output

    Add a flag to emit ASCII-only output

    I'm working with Sass 3.4.

    My sass source code is:

    #test
      content:  "\f000"
    

    when parsed it got converted to:

    #test {
      content: "";
    }
    

    I'm using expanded style and sass syntax. I've noticed that switching to scss works correctly, anyway my entire codebase is in sass format :(

    Is there any way to preserve original content unicode string?

    Thanks in advance

    enhancement help wanted 
    opened by dwightjack 102
  • Extending a compound selector violates extend semantics

    Extending a compound selector violates extend semantics

    Currently, when a compound selector is extended, Sass will only replace instances of the full extendee with the extender. For example:

    .a {x: y}
    .b {x: y}
    .a.b {x: y}
    
    .c {@extend .a.b}
    

    produces

    .a {x: y}
    .b {x: y}
    .a.b, .c {x: y}
    

    when it should produce

    .a, .c {x: y}
    .b, .c {x: y}
    .a.b, .c {x: y}
    

    according to the semantics of @extend. We should fix this, especially as CSS moves closer to supporting @extend natively.

    Tasks:

    • [x] Deprecate existing behavior in stable.
    • [x] Remove behavior from master.
    bug CSS compatibility requires deprecation 
    opened by nex3 95
  • Variables in @import

    Variables in @import

    Currently when using @import, you need to hardcode in uri. I'd like the ability to pass in a variable/function call to get the uri and use that for the @import call, something like the following:

    @function drupal-theme($project, $append: '') {
      @return /sites/all/themes/#{$project}/#{$append};
    }
    …
    @import #{drupal-theme('my-theme', 'sass/style)};
    

    Which would be the same as:

    @import '/sites/all/themes/my-theme/sass/style';
    

    This would also make it easier for a master import for sub-partials a la Compass framework stuff:

    $compass-css3: 'border-radius' 'inline-block' 'opacity' 'box-shadow' 'text-shadow'…;
    @each $css3 in $compass-css3 {
      @import 'css3/#{$css3};
    }
    
    opened by Snugug 95
  • Sass style mixins in SCSS

    Sass style mixins in SCSS

    I'd love Sass style mixins in SCSS, specifically being able to do + in addition to @include. I know a few others mentioned this recently, but I didn't see an official issue for it, so I'm adding one.

    If not, I guess I'm going to need to start learning Sass syntax.

    enhancement under consideration 
    opened by Snugug 91
  • Add a module system

    Add a module system

    See also the module system project.


    This is a compilation of issues and wishes about @import

    Import CSS files #556

    @import "normalize";
    

    Would import sass, scss or css file

    There's a plugin for that

    Import Once #139

    @import-once "foo";
    @import "foo" !once;
    @depend "foo";
    

    Multiple syntax suggestions for one time import

    There is a plugin for that

    Import Directory #690

    @import "foo";

    If "foo" is a folder than it tries to import "foo/_module.scss"

    reasonable

    Namespaces and Aliases #353

    @import "foo" as "bar";
    

    This would put every "foo" components (mixins, vars, placeholders...) in a "bar" package.

    What would be the separator ? . or / or \ or :: ? Where would go the $ and % ? Before or after the namespace ? What it would look like :

    // Mixins
    @include bar.baz();
    or
    @include bar/baz();
    
    // Variables
    color: $bar.baz;
    or
    color: bar.$baz;
    or
    color: $bar/baz;
    or
    color: bar/$baz;
    
    // Placeholders
    div { @extend %bar.baz; }
    or
    div { @extend bar.%baz; }
    or
    div { @extend %bar/baz; }
    or
    div { @extend bar/%baz; }
    
    // Functions
    color: bar.baz();
    or
    color: bar/baz();
    

    Non-transitive imports #353

    if A imports B and B imports C, A shouldn't necessarily see everything from C. A way of getting around non-transitive imports.

    Renaming classes #353

    This isn't something I'm 100% sold on, but it has been requested. Maybe the correct way to do this is some combination of namespacing and @extend.

    Disabling CSS output #353

    Both selectively and wholesale. The importer may want to @extend the rules in the importee but not have them concretely present, or it may want to suppress rules matching a certain selector.

    This is also related to #320 :

    // A.scss
    .foo {...}
    .bar {...}
    
    // B.scss
    @use "A";
    .baz { @extend .foo; }
    

    B output would not contain .foo & .bar definition but only .baz;

    Conditional imports #451

    @if true {
        @import "foo";
    }
    

    It "worked" before but never intended.

    Paths

    A way to setup shortcut paths (like Require.js)

    // No syntax intended, only the purpose
    @paths (
        "bootstrap": "../components/bootstrap-sass/vendor/assets/stylesheets/bootstrap"
    );
    
    @import "bootstrap";
    
    enhancement specs written 
    opened by JulienCabanes 87
  • Preserve author's color format

    Preserve author's color format

    Unless the output format is compressed, we should preserve the format that the author used when creating a color.

    Formats being:

    • color name
    • hex
    • rgb/rgba
    • hsl/hsla

    The format should be sticky to derived values in as much as possible.

    enhancement planned 
    opened by chriseppstein 85
  • Disable converting hsl()/hsla()

    Disable converting hsl()/hsla()

    When using hsl()/hsla(), it will be converted into hex or rgba. But i want to keep my original hsl/hsla expression. This has different matters:

    • hsl accepts floating point numbers like hsl(85.3, 20.3, 75.8). The precision will be lost, when converting to hex.
    • when converting from hsla to rgba, precision will be lost, too.
    • My applications "reads" the style sheet rules, and want to extract the hsl/hsla expressions, but there are no more.
    • My application uses the extracted hsl/hsla expressions for another color manipulations (at runtime, not a compile time!). Precision is very important. I work a lot of with colors.

    So, can you offer a command line option, that will keep all plain hsl/hsla expressions? This would be amazing.

    PS: I do not support IE8 or below, so don't worry. But even IE9 accepts floating point hsl/hsla-values, all html5 browsers can do this, and my applications requieres html5 only browsers.

    Greetings, Sebastian

    opened by arakis 83
  • Variable interpolation don't work inside @each rules

    Variable interpolation don't work inside @each rules

    $ck: #66cc00; $es: #3366cc; $fr: #ff6c00; $bd: #cc0000; $wt: #FFDB00;

    @each $brand in ck, es, fr, bd, wt{ .#{$brand}_bg { background-color: $#{$brand}; // <-- I want to call $ck, $es, $fr, $bd, $wt } }

    opened by ghost 83
  • Bump tj-actions/changed-files from 34.5.3 to 35.2.0

    Bump tj-actions/changed-files from 34.5.3 to 35.2.0

    Bumps tj-actions/changed-files from 34.5.3 to 35.2.0.

    Release notes

    Sourced from tj-actions/changed-files's releases.

    v35.2.0

    What's Changed

    New Contributors

    Full Changelog: https://github.com/tj-actions/changed-files/compare/v35...v35.2.0

    v35.1.2

    What's Changed

    Full Changelog: https://github.com/tj-actions/changed-files/compare/v35...v35.1.2

    v35.1.1

    What's Changed

    Full Changelog: https://github.com/tj-actions/changed-files/compare/v35...v35.1.1

    v35.1.0

    What's Changed

    Full Changelog: https://github.com/tj-actions/changed-files/compare/v35...v35.1.0

    v35.0.1

    What's Changed

    Full Changelog: https://github.com/tj-actions/changed-files/compare/v35...v35.0.1

    ... (truncated)

    Changelog

    Sourced from tj-actions/changed-files's changelog.

    Changelog

    v35.2.0 (2022-12-30)

    Full Changelog

    v35 (2022-12-30)

    Full Changelog

    Fixed bugs:

    • [BUG] files_ignore used with files not ignoring as expected #901

    Merged pull requests:

    v35.1.2 (2022-12-29)

    Full Changelog

    Closed issues:

    • Dependency Dashboard #27

    Merged pull requests:

    v35.1.1 (2022-12-26)

    Full Changelog

    Implemented enhancements:

    • [Feature] Output which file changed from files input #895

    Fixed bugs:

    • pipeline failed in tj-action #894

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • SCSS member loading does not work with @use directive

    SCSS member loading does not work with @use directive

    In the documentation for @use, it states that

    You can access variables, functions, and mixins from another module by writing <namespace>.<variable>, <namespace>.<function>(), or @include <namespace>.<mixin>(). By default, the namespace is just the last component of the module’s URL.

    https://sass-lang.com/documentation/at-rules/use#loading-members

    However, I could not get @include <namespace>.<mixin>(arguments) or @include <namespace>.<mixin> to work when I used the @use to import my mixin. I originally had this issue in Hugo, but I reproduced it in React with node-sass

    post.scss

    $var: yellow;
    @mixin mix1($arg1, $arg2) {
      background-color: red;
    }
    
    @mixin mix2 {
      background-color: blue;
    }
    

    App.scss

    @use "src/post" as c;
    
    .App {
      @include c.mix2(1px, 2px);
      @include c.mix1;
      background-color: c.$var;
    }
    

    Error image image image

    Steps to reproduce I'm not familiar how to minimally produce with only node-sass, so React was the quickest option for me

    1. Use node-sass version
    node-sass       8.0.0   (Wrapper)       [JavaScript]
    libsass         3.5.5   (Sass Compiler) [C/C++]
    
    1. Create a new react app with npx create-react-app my-app
    2. Replace all .css files with scss and use code blocks above

    Steps taken to address

    • Tried using with and without different namespace with @use "src/post" as c
    • Tried making post.scss private _post.scss like the example in the documentation link
    opened by kalinkochnev 0
  • Color Spaces: Should we deprecate alpha?

    Color Spaces: Should we deprecate alpha?

    The Color Spaces proposal currently deprecates all channel accesor functions except alpha()/color.alpha(). Was this an oversight or did we have some justification for it?

    enhancement proposal: color spaces 
    opened by nex3 2
  • Color Spaces: Unquoted channel names play poorly with RGB

    Color Spaces: Unquoted channel names play poorly with RGB

    The Color Spaces proposal currently requires channel names to be unquoted strings for functions like color.channel() and color.is-powerless(). While this matches the requirement that color spaces be unquoted, it raises a serious problem: the channel names red, green, and blue for the various predefined color spaces will be parsed by Sass as color values rather than unquoted strings, making color.channel($color, red) throw an error. While this could be worked around with color.channel($color, unquote("red")), that's obviously infeasible in practice.

    I see three basic approaches we could take here:

    1. Require quoted strings instead. This avoids any ambiguity issues, but it's inconsistent with color space names which require unquoted strings and aren't ambiguous with predefined colors. We could also take this a step further and change color spaces to require quoted strings as well for consistency, but then that's inconsistent with how they're written in plain CSS (particularly the color() function and the <color-interpolation-method> production, the latter of which we want to accept as-is for the mix function).

    2. Switch to CSS's channel terminology. Colors 5 defines relative color syntax which makes explicit reference to channel names, but (other than alpha) they're different than the names we use. In particular, they're all single letters: r, g, b; l, c, h; and so on. While this is less obvious to a reader, there's real value in being consistent with CSS in addition to avoiding ambiguity with color names. If we did go this route, though, we'd need to consider whether to deprecate the existing long-form argument names for color.adjust(), .scale(), and .change().

    3. Hack around the issue entirely by defining #f00, #0f0, and #00f as value aliases of the channel names red, green, and blue. This is extremely messy so I'm inclined to dislike it, but it may be the path of least resistance.

    bug proposal: color spaces 
    opened by nex3 1
  • [Color Spaces] Explicitly specify deprecated color functions

    [Color Spaces] Explicitly specify deprecated color functions

    The current color spaces proposal PR doesn't explicitly specify how to handle most of the deprecated color functions. It's reasonable to assume they work more or less the same way they always did, but as I get into the weeds of the implementation I'm realizing that because the internal representation of colors has changed so much these functions should probably also get explicitly defined.

    Some particular questions I've run into:

    • Should functions like adjust-hue() return a color in the original space or in HSL? (Probably original to match our general design principle that only color.to-space() changes the color space.)

    • Should hue() return the hue % 360deg? We currently store the hue as written, but taking the mod here would preserve some edge-case backwards compatibility.

    • Should channel-access functions like red(), hue(), and so on even allow legacy colors? My current implementation forbids them.

    enhancement proposal: color spaces 
    opened by nex3 1
  • Could not find an option named

    Could not find an option named "scss".

    Strange thing happening here. As the title says, I am getting "Could not find an option named "scss".

    "scripts": {
        "start": "concurrently \"npm run serve\" \"npm run build:watch\" \"npm run compile:sass\"",
        "compile:sass": "sass ./src/styles:./src/styles -w",
    },
    
    needs info 
    opened by bsastregx 1
Releases(3.4.21)
A declarative, HTML-based language that makes building web apps fun

A declarative, HTML-based language that makes building web apps fun ?? Docs ∙ Try Online ∙ Contribute ∙ Get Support Intro Marko is HTML re-imagined as

Marko 12k Jan 3, 2023
Makes typing in input fields fun with CSS3 effects

Fancy Input Makes typing & deleting in input/Textarea fields exciting & fun with CSS3 effects. View Demo Page Basic use example: <!-- ...previous page

Yair Even Or 1.9k Jan 2, 2023
A declarative, HTML-based language that makes building web apps fun

A declarative, HTML-based language that makes building web apps fun ?? Docs ∙ Try Online ∙ Contribute ∙ Get Support Intro Marko is HTML re-imagined as

Marko 12k Jan 3, 2023
DisOwen project - Makes it easy and fun to use Discord

DisOwen project - Makes it easy and fun to use Discord. Also first userbot for Discord

Ber4tbey 7 Aug 4, 2022
A tiny wrapper around pg that makes PostgreSQL a lot of fun to use. Written in TypeScript.

A tiny wrapper around pg that makes PostgreSQL a lot of fun to use. Written in TypeScript.

Mojolicious 8 Nov 29, 2022
Lavanstax project - Makes it easy and fun to use İnstagram. Also first userbot for İnstagram

Lavanstax Lavanstax project - Makes it easy and fun to use İnstagram. Also first userbot for İnstagram | İnstagram | Telegram Channel | Telegram Group

Berathan Yedibela 19 Oct 15, 2022
Source code for Chrome/Edge/Firefox/Opera extension Magic CSS (Live editor for CSS, Less & Sass)

Live editor for CSS, Less & Sass (Magic CSS) Extension Live editor for CSS, Less & Sass (Magic CSS) for Google Chrome, Microsoft Edge, Mozilla Firefox

null 210 Dec 13, 2022
A Browser extension that not only makes your browsing experience safe but makes it optimized

Sia Sia is a browser extension that not only makes your browsing experience safe but makes it optimized Table of Contents About The Project Built With

Arun Govind M 14 Feb 23, 2022
A JavaScript module that shortens your code, makes life easier, and makes development faster!

Quxt A JavaScript module that shortens your code, makes life easier, and makes development faster! Installation npm install quxt Quick Start Check ind

Qux App 5 May 8, 2022
A simple CSS tooltip made with Sass

Simptip [v1.0.4] A simple CSS tooltip made with Sass Visit Site, Documentation and some examples Installation Install with npm, Yarn or Bower: npm: np

Arash Manteghi 650 Dec 14, 2022
A CSS button library built using Sass and Compass

Buttons 2.0 Buttons 2.0 Buttons is a highly customizable production ready mobile web and desktop css button library. Buttons is a free open source pro

Alex Wolfe 5.1k Jan 4, 2023
💅 A ready-to-go with a well-thought-out structure Electron app boilerplate with ReactJS, TypeScript, CSS / SASS modules, SWC, Eslint, Prettier, GitHub Action releases and more.

Electron App ??  A ready-to-go with a well-thought-out structure Electron app boilerplate with ReactJS, TypeScript, CSS / SASS modules, SWC, Eslint, P

Dalton Menezes 155 Dec 29, 2022
Convert css (scss/sass) to vanilla-extract.

CSS-to-vanilla-extract ⚡ Welcome ?? Convert CSS (SCSS/SASS) to vanilla-extract. playground Install npm i -D c2ve Usage Once installed, you can run it

j1ngzoue 31 Jan 4, 2023
iHover is a collection of hover effects using pure CSS, inspired by codrops article, powered by Sass.

Intro iHover is a collection of hover effects using pure CSS, inspired by this codrops article, powered by Sass. Demo: https://gudh.github.io/ihover/d

null 3.5k Jan 4, 2023
:iphone: A super lightweight HTML, Sass, CSS, and JavaScript framework for building responsive websites

Responsive Boilerplate A powerful, accessible, developer friendly, framework for building responsive websites Responsive Boilerplate is the developers

ResponsiveBP 845 Dec 22, 2022
A library of icons rendered purely in CSS and compiled using SASS.

Welcome to PureIcons.css: This is a library of icons rendered purely in CSS and compiled using SASSs. It is currently at 79 icons. More will be added

William Troup 2 Apr 27, 2021
Animatelo is a bunch of cool, fun, and cross-browser animations for you to use in your projects. This is a porting to Web Animation API of the fabulous animate.css project.

Animatelo Just-add-water Web Animations Animatelo is a bunch of cool, fun, and cross-browser animations for you to use in your projects. Great for emp

GibboK 477 Nov 12, 2022
Giggy is a collection of a few fun jokes related to Coding & Dark Humor - Created using HTML, JavaScript, CSS & Webpack.

Giggy A Collection of some of the best jokes. This is a Web Application with some jokes related to coding & Dark Humor. Created with data from the Jok

Awais Amjed 7 Jul 28, 2022
Clinton Mbonu 20 Jun 30, 2022
This is a Tic Tac Toe game built with HTML, CSS, and JavaScript. It is a simple and fun game where two players take turns marking X and O on a 3x3 grid.

Tic Tac Toe Game This is a Tic Tac Toe game built with HTML, CSS, and JavaScript. It is a simple and fun game where two players take turns marking X a

Andrew Tsegaye 4 Mar 4, 2023