---
title: Sass's `@content` Directive Use Cases
teaser: |
  See examples of how the Sass `@content` directive
  can empower us to remove duplication in our SCSS,
  and think more creatively about its organization and implementation.
tags: sass,design
author: Christian Reuter
published_on: 2014-04-22
---

Sass 3.2 added the [`@content` directive][`@content` directive], which allows
us to pass a content block into a mixin.

[`@content` directive]: http://sass-lang.com/documentation/file.SASS_REFERENCE.html#mixin-content

```scss
@mixin apply-to-ie6-only {
  * html {
    @content
  }
}

@include apply-to-ie6-only {
  #logo {
    background-image: url(/logo.gif);
  }
}
```

Generates:

```css
* html #logo {
  background-image: url(/logo.gif);
}
```

We can use it anywhere that declarations need to be wrapped in outer-scoped
selectors, and many places where declarations are duplicated.

## Media Queries

We can inline our media queries rather than maintaining separate,
device-specific stylesheets, but writing queries over and over can get pretty
unwieldy. We can simplify them by passing a content block into a mixin that
wraps a query.

```scss
@mixin media($width) {
  @media only screen and (max-width: $width) {
    @content;
  }
}

@include media(320px) {
  background: red;
}
```

Generates:

```css
@media only screen and (max-width: 320px) {
  background: red;
}
```

This becomes especially helpful for long, highly specific media queries, like
the [HiDPI mixin][HiDPI mixin] we use in Bourbon.

[HiDPI Mixin]: http://bourbon.io/docs/#hidpi-media-query

You can see our full `@media` mixin in [Neat][Neat].

[Neat]: https://github.com/thoughtbot/neat/blob/master/app/assets/stylesheets/grid/_media.scss

## Keyframes

Keyframes are a good example of content duplication. Rather than rewriting the
declarations for each vendor-specific selector, we can instead write a mixin to
do it for us.

```scss
@mixin keyframes($name) {
  @-webkit-keyframes #{$name} {
    @content;
  }

  @-moz-keyframes #{$name} {
    @content;
  }

  @keyframes #{$name} {
    @content;
  }
}

@include keyframes(fadeIn) {
  from {
    opacity: 0%;
  }
  to {
    opacity: 100%;
  }
}
```

Generates:

```css
@-webkit-keyframes fadeIn {
  from {
    opacity: 0%;
  }
  to {
    opacity: 100%;
  }
}

@-moz-keyframes fadeIn {
  from {
    opacity: 0%;
  }
  to {
    opacity: 100%;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0%;
  }
  to {
    opacity: 100%;
  }
}
```

This is also used in [Bourbon][Bourbon].

[Bourbon]: http://bourbon.io/docs/#keyframes

## Context Specificity

I just picked up a project from [Reda Lemeden][Reda-Lemeden], who wrote a pair
of clever mixins to modify components for a given context.

[Reda-Lemeden]: http://twitter.com/kaishin

Instead of creating many `.component--modifiers` or chaining modifying classes,
we can better separate our concerns by defining a style's context specificity.

```scss
@mixin create-context($classes...) {
  @each $class in $classes {
    .#{$class} & {
      @content;
  }
}

@mixin context--alternate-template {
  @include create-context(about, blog) {
    @content
  }
}

.header {
  height: 12em;
  background: red;

  @include context--alternate-template {
    background: green;
  }
}
```

Generates:

```css
.header {
  height: 12em;
  background: red;
}

.about .header {
  background: green;
}

.blog .header {
  background: green;
}
```

## Getting BEMy

Sass 3.3 adds the `@at-root` directive and improved `&`s. The former allows us
to nest declarations in Sass, but compile them to the stylesheet's root. The
latter appends any following text directly to the parent's selector.

These can be used with `@content` to simplify writing [BEM][BEM] syntax. Thanks
to [Scott Kellum][Scott Kellum] for the
[original implementation][original-implementation].

[original-implementation]: http://sassmeister.com/gist/6994632

[BEM]: http://getbem.com/introduction/
[Scott Kellum]: http://www.scottkellum.com

```scss
@mixin element($name) {
  @at-root #{&}__#{$name} {
    @content;
  }
}

@mixin modifier($name) {
  @at-root #{&}--#{$name} {
    @content;
  }
}

.block {
  color: red;

  @include element(element) {
    color: green;

    @include modifier(modifier) {
      color: blue;
    }
  }
}
```

Generates:

```css
.block {
  color: red;
}

.block__element {
  color: green;
}

.block__element--modifier {
  color: blue;
}
```

## In Conclusion

`@content` is just one of many Sass directives that can empower us to remove
duplication in our SCSS, and think more creatively about its organization and
implementation.  Learn more by reading the [Sass directives
documentation][directives-documentation].

[directives-documentation]: http://sass-lang.com/documentation/file.SASS_REFERENCE.html#directives
