CSS PREprocessors

Content Directive

by

The @content directive is a way to pass a block of styles to a mixin, this is useful in cases when you don't want to limit your future self in terms of number of parameters a mixin can accept.

Basic use

The @content directive allows you to use a common set of selectors everywhere you declare a mixin.

.active(@content) {
  &.is-active,
  &:hover {
    @content();
  }
}

.content-directive {
  foo: bar;
  .active({
    baz: qux
  });
}
@mixin active {
  &.is-active,
  &:hover {
    @content;
  }
}

.content-directive {
  foo: bar;
  @include active {
    baz: qux;
  }
}
=active()
  &.is-active,
  &:hover
    @content

.content-directive
  foo: bar
  +active()
    baz: qux
active()
  &.is-active,
  &:hover
    {block}

.content-directive
  foo: bar
  +active()
    baz: qux
@define-mixin active {
  &.is-active,
  &:hover {
    @mixin-content;
  }
}

.content-directive {
  foo: bar;
  @mixin active {
    baz: qux;
  }
}
.content-directive {
  foo: bar;
}
.content-directive.is-active,
.content-directive:hover {
  baz: qux;
}

Notice that for Stylus, we need a + before calling the mixin every time when you're passing content to it (below it, indented).

Simpler media queries

You can use the @content directive to simplify your responsive styles:

.media-max(@num, @content) {
  @media only screen and (max-width: @num) {
    @content();
  }
}

.media-test {
  width: 400px;
  .media-max(980px, {
    max-width: 100%;
  });
}
@mixin media-max($num) {
  @media only screen and (max-width: $num) {
    @content;
  }
}

.media-test {
  width: 400px;
  @include media-max(980px) {
    max-width: 100%;
  }
}
=media-max($num)
  @media only screen and (max-width: $num)
    @content

.media-test
  width: 400px
  +media-max(980px)
    max-width: 100%
media-max($num)
  @media only screen and (max-width: $num)
    {block}

.media-test
  width: 400px
  +media-max(980px)
    max-width: 100%
@define-mixin media-max $num {
  @media only screen and (max-width: $num) {
    @mixin-content;
  }
}
.media-test {
  width: 400px;
  @mixin media-max 980px {
    max-width: 100%;
  }
}
.media-test {
  width: 400px;
}
@media only screen and (max-width: 980px) {
  .media-test {
    max-width: 100%;
  }
}

Placeholder pseudo element

Another very useful case where the @content directive can help is when defining styles for placeholder text - you can put a @content directive in each vendor-specific selector (can also be used for keyframes which are still prefixed). An alternative to the code snippets below would be to just use Autoprefixer.

.placeholder-text(@content) {
  &::-webkit-input-placeholder {
    @content();
  }
  &::-moz-placeholder {
    @content();
  }
  &:-ms-input-placeholder {
    @content();
  }
  &::placeholder {
    @content();
  }
}

.text-input {
  .placeholder-text({
    color: #acacac;
    text-transform: uppercase;
  });
}
@mixin placeholder-text {
  &::-webkit-input-placeholder {
    @content;
  }
  &::-moz-placeholder {
    @content;
  }
  &:-ms-input-placeholder {
    @content;
  }
  &::placeholder {
    @content;
  }
}

.text-input {
  @include placeholder-text {
    color: #acacac;
    text-transform: uppercase;
  }
}
=placeholder-text()
  &::-webkit-input-placeholder
    @content

  &::-moz-placeholder
    @content

  &:-ms-input-placeholder
    @content

  &::placeholder
    @content

.text-input
  +placeholder-text()
    color: #acacac
    text-transform: uppercase
placeholder-text()
  &::-webkit-input-placeholder
    {block}

  &::-moz-placeholder
    {block}

  &:-ms-input-placeholder
    {block}

  &::placeholder
    {block}

.text-input
  +placeholder-text()
    color: #acacac
    text-transform: uppercase
@define-mixin placeholder-text {
  &::-webkit-input-placeholder {
    @mixin-content;
  }
  &::-moz-placeholder {
    @mixin-content;
  }
  &:-ms-input-placeholder {
    @mixin-content;
  }
  &::placeholder {
    @mixin-content;
  }
}

.text-input {
  @mixin placeholder-text {
    color: #acacac;
    text-transform: uppercase;
  }
}
.text-input::-webkit-input-placeholder {
  color: #acacac;
  text-transform: uppercase;
}
.text-input::-moz-placeholder {
  color: #acacac;
  text-transform: uppercase;
}
.text-input:-ms-input-placeholder {
  color: #acacac;
  text-transform: uppercase;
}
.text-input::placeholder {
  color: #acacac;
  text-transform: uppercase;
}

To learn more about placeholder text styling I recommend reading this great article by Treehouse, it explains nicely what can and cannot be styled about the placeholder text.

Interactive

Leave a comment below or suggest improvements on GitHub.