CSS At-Rules

Compatibility (Name Interpolation):
Dart Sass
since 1.15.0
LibSass
βœ—
Ruby Sass
βœ—

LibSass, Ruby Sass, and older versions of Dart Sass don’t support interpolation in at-rule names. They do support interpolation in values.

Sass supports all the at-rules that are part of CSS proper. To stay flexible and forwards-compatible with future versions of CSS, Sass has general support that covers almost all at-rules by default. A CSS at-rule is written @<name> <value>, @<name> { ... }, or @<name> <value> { ... }. The name must be an identifier, and the value (if one exists) can be pretty much anything. Both the name and the value can contain interpolation.

Playground

SCSS Syntax

@namespace svg url(http://www.w3.org/2000/svg);

@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}

@counter-style thumbs {
  system: cyclic;
  symbols: "\1F44D";
}
Playground

Sass Syntax

@namespace svg url(http://www.w3.org/2000/svg)

@font-face
  font-family: "Open Sans"
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2")

@counter-style thumbs
  system: cyclic
  symbols: "\1F44D"


CSS Output

@charset "UTF-8";
@namespace svg url(http://www.w3.org/2000/svg);
@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}
@counter-style thumbs {
  system: cyclic;
  symbols: "πŸ‘";
}

If a CSS at-rule is nested within a style rule, the two automatically swap positions so that the at-rule is at the top level of the CSS output and the style rule is within it. This makes it easy to add conditional styling without having to rewrite the style rule’s selector.

Playground

SCSS Syntax

.print-only {
  display: none;

  @media print { display: block; }
}



Playground

Sass Syntax

.print-only
  display: none

  @media print
    display: block



CSS Output

.print-only {
  display: none;
}
@media print {
  .print-only {
    display: block;
  }
}

@media@media permalink

Compatibility (Range Syntax):
Dart Sass
since 1.11.0
LibSass
βœ—
Ruby Sass
since 3.7.0

LibSass and older versions of Dart Sass and Ruby Sass don’t support media queries with features written in a range context. They do support other standard media queries.

Playground

SCSS Syntax

@media (width <= 700px) {
  body {
    background: green;
  }
}
Playground

Sass Syntax

@media (width <= 700px)
  body
    background: green


CSS Output

@media (width <= 700px) {
  body {
    background: green;
  }
}

The @media rule does all of the above and more. In addition to allowing interpolation, it allows SassScript expressions to be used directly in the feature queries.

Playground

SCSS Syntax

$layout-breakpoint-small: 960px;

@media (min-width: $layout-breakpoint-small) {
  .hide-extra-small {
    display: none;
  }
}
Playground

Sass Syntax

$layout-breakpoint-small: 960px

@media (min-width: $layout-breakpoint-small)
  .hide-extra-small
    display: none


CSS Output

@media (min-width: 960px) {
  .hide-extra-small {
    display: none;
  }
}


When possible, Sass will also merge media queries that are nested within one another to make it easier to support browsers that don’t yet natively support nested @media rules.

Playground

SCSS Syntax

@media (hover: hover) {
  .button:hover {
    border: 2px solid black;

    @media (color) {
      border-color: #036;
    }
  }
}

Playground

Sass Syntax

@media (hover: hover)
  .button:hover
    border: 2px solid black

    @media (color)
      border-color: #036




CSS Output

@media (hover: hover) {
  .button:hover {
    border: 2px solid black;
  }
}
@media (hover: hover) and (color) {
  .button:hover {
    border-color: #036;
  }
}

@supports@supports permalink

The @supports rule also allows SassScript expressions to be used in the declaration queries.

Playground

SCSS Syntax

@mixin sticky-position {
  position: fixed;
  @supports (position: sticky) {
    position: sticky;
  }
}

.banner {
  @include sticky-position;
}
Playground

Sass Syntax

@mixin sticky-position
  position: fixed
  @supports (position: sticky)
    position: sticky



.banner
  @include sticky-position

CSS Output

.banner {
  position: fixed;
}
@supports (position: sticky) {
  .banner {
    position: sticky;
  }
}


@keyframes@keyframes permalink

The @keyframes rule works just like a general at-rule, except that its child rules must be valid keyframe rules (<number>%, from, or to) rather than normal selectors.

Playground

SCSS Syntax

@keyframes slide-in {
  from {
    margin-left: 100%;
    width: 300%;
  }

  70% {
    margin-left: 90%;
    width: 150%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
Playground

Sass Syntax

@keyframes slide-in
  from
    margin-left: 100%
    width: 300%


  70%
    margin-left: 90%
    width: 150%


  to
    margin-left: 0%
    width: 100%


CSS Output

@keyframes slide-in {
  from {
    margin-left: 100%;
    width: 300%;
  }
  70% {
    margin-left: 90%;
    width: 150%;
  }
  to {
    margin-left: 0%;
    width: 100%;
  }
}