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.