discuss
discuss copied to clipboard
@apply cannot be used with .container because .container is included in multiple rulesets.
First of all, thank for this very fine tool, @adamwathan!
I'm using tailwind in my grunt setup and I'm having a problem using apply. Don't know what I'm doing wrong. Maybe I am not supposed to use it with .container but the docs are not saying anything about that so I guess I have to ask.
So, this works just fine:
.c-sidenav { @apply .bg-ocean .py-3; }
This gives me a fatal error:
.c-sidenav { @apply .container .bg-ocean .py-3; }
Error says: @apply
cannot be used with .container because .container is included in multiple rulesets.
If you need any other information about my setup, please let me know. Just in case, here's a simple version of the file which fails to compile.
/**
- This injects Tailwind's base styles, which is a combination of
- Normalize.css and some additional base styles.
- You can see the styles here:
- https://github.com/tailwindcss/tailwindcss/blob/master/css/preflight.css
- If using
postcss-import
, use this import instead:- @import "tailwindcss/preflight"; / @tailwind preflight; /*
- This injects any component classes registered by plugins.
- If using
postcss-import
, use this import instead:- @import "tailwindcss/components"; / @tailwind components; /*
- Here you would add any of your custom component classes; stuff that you'd
- want loaded before the utilities so that the utilities could still
- override them.
- Example:
- .btn { ... }
- .form-input { ... }
- Or if using a preprocessor or
postcss-import
:- @import "components/buttons";
- @import "components/forms"; / /*
- This injects all of Tailwind's utility classes, generated based on your
- config file.
- If using
postcss-import
, use this import instead:- @import "tailwindcss/utilities"; / @tailwind utilities; /*
- Here you would add any custom utilities you need that don't come out of the
- box with Tailwind.
- Example :
- .bg-pattern-graph-paper { ... }
- .skew-45 { ... }
- Or if using a preprocessor or
postcss-import
:- @import "utilities/background-patterns";
- @import "utilities/skew-transforms"; */ .c-sidenav { @apply .container .bg-ocean .py-3; }
Hey @Benecke thanks for the kind words!
The error in this case is correct — the .container
class is a complex component class and not just a simple utility so it can't be mixed in.
Here are the rulesets for .container
:
.container {
width: 100%;
}
@media (min-width: 576px) {
.container {
max-width: 576px;
}
}
@media (min-width: 768px) {
.container {
max-width: 768px;
}
}
@media (min-width: 992px) {
.container {
max-width: 992px;
}
}
@media (min-width: 1200px) {
.container {
max-width: 1200px;
}
}
@apply
is only meant for mixing in single-definition utilities, not complex rules, and since we haven't made any decisions about the proper behavior for mixing in complex rules, we explicitly error to avoid people depending on what is currently undefined behavior.
Out of curiousity, with your example, what would you expect the exact output to be?
For reference, this is what Less does, which is where the idea for @apply
came from:
http://lesscss.org/less-preview/#%7B%22less%22%3A%22.container%20%7B%5Cn%20%20width%3A%20100%25%3B%5Cn%7D%5Cn%5Cn%40media%20(min-width%3A%20576px)%20%7B%5Cn%20%20.container%20%7B%5Cn%20%20%20%20max-width%3A%20576px%3B%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn%40media%20(min-width%3A%20768px)%20%7B%5Cn%20%20.container%20%7B%5Cn%20%20%20%20max-width%3A%20768px%3B%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn%40media%20(min-width%3A%20992px)%20%7B%5Cn%20%20.container%20%7B%5Cn%20%20%20%20max-width%3A%20992px%3B%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn%40media%20(min-width%3A%201200px)%20%7B%5Cn%20%20.container%20%7B%5Cn%20%20%20%20max-width%3A%201200px%3B%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn.c-sidenav%20%7B%5Cn%20%20.container%3B%5Cn%7D%22%7D
Thanks for clearing that up for me.
Out of curiousity, with your example, what would you expect the exact output to be?
Well, I didn't really think about it that much but seeing your code I'd expect it to do something like a sass extend, like so.
.container
.c-sidenav {
width: 100%;
}
@media (min-width: 576px) {
.container,
.c-sidenav {
max-width: 576px;
}
}
@media (min-width: 768px) {
.container,
.c-sidenav {
max-width: 768px;
}
}
@media (min-width: 992px) {
.container,
.c-sidenav {
max-width: 992px;
}
}
@media (min-width: 1200px) {
.container,
.c-sidenav {
max-width: 1200px;
}
}
The reason I was trying to apply .container was, that I was thinking about making the wrapper (container) part of a custom component (with a bem name instead of the tailwind name). Maybe not a good idea anyway. I will use the tailwind names in my markup for those things and see how far I can get.
Thanks again for the fast response!
I wanted to apply .container
in case body has a .has-fixed-header
class. The code I tried is this:
body.has-fixed-header #nav {
@apply container;
}
It would be great if we can make this container stuff work with @apply
.
A way to circumvent the issue and allow users to use @apply container;
would be adding postcss-import
to core's dependencies. Then we could change the source CSS to something like this:
.container {
width: 100%;
@media (min-width: 576px) { max-width: 576px; }
@media (min-width: 768px) { max-width: 768px; }
@media (min-width: 992px) { max-width: 992px; }
@media (min-width: 1200px) { max-width: 1200px; }
}
This is 100% compatible with the way @apply
works currently but imho I think it's more important to discuss if and how this complex scenarios should/could be handled ✌️
Also keep in mind Adam mentioned (can't find the issue right now) some of this undocumented things kinda work by accident (not design) and any change that would make them stop working wouldn't be considered a breaking change.
I wanted something that would respect the current project's parameters for screen size so I did this instead. Still wish i could use container =\
.fake-container {
width: 100%;
@screen sm {
max-width: theme('screens.sm');
}
@screen md {
max-width: theme('screens.md');
}
@screen lg {
max-width: theme('screens.lg');
}
@screen xl {
max-width: theme('screens.xl');
}
}