Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calc is not supported as an [arbitrary] container size #5

Closed
Serator opened this issue Dec 25, 2022 · 3 comments
Closed

Calc is not supported as an [arbitrary] container size #5

Serator opened this issue Dec 25, 2022 · 3 comments
Assignees

Comments

@Serator
Copy link

Serator commented Dec 25, 2022

What version of @tailwindcss/container-queries are you using?

0.1.0

What browser are you using?

Chrome 108.0.5359.125

What operating system are you using?

Windows

Reproduction repository

https://play.tailwindcss.com/ZJqWpcCdgG

Describe your issue

I would like to use calc as the container size. This works in CSS, but doesn't work in Tailwind.
https://chromestatus.com/feature/5643732019838976 - a grain of information as to why this should work.
CSS version works in Chrome 108, Firefox 110 Nightly (stable does not support CQ yet), Safari (some of the latest version).

@adamwathan
Copy link
Member

Just a note for when we get back from the holidays — I'm guessing this is because it becomes hard to sort, and we need variants to sort deterministically in the resulting stylesheet for your site to render as expected. We are probably dropping this value completely because we're interpreting it as unsortable, which is maybe not actually true as long as only one unit is used in the calculation.

@RobinMalfait
Copy link
Contributor

Correct @adamwathan, we explicitly parse the value and check for numbers so that we can guarantee sorting. We could make this a bit more flexible as you mentioned if you are using the same unit but that breaks down fairly quickly if you start using calc like in @Serator's example or it becomes impossible when you start using custom properties since those can change at runtime.

Maybe we can apply some different sorting heuristics:

  • No sorting at all
  • Whatever is detected first, will be used first in the stylesheet
  • Sort numbers relative to each other, move unparsable values to the end but maintain the order they first appeared in
  • Maintain sort order from the defined values in your config (you are sorting)
  • A combination of the above heuristics

@reinink reinink self-assigned this Sep 7, 2023
@reinink
Copy link
Member

reinink commented Sep 7, 2023

Hey! Apologies on the delay here. I've been catching up on older issues this week and finally had a chance to dig into this one a little deeper.

Unfortunately there isn't a reliable way for us to support calc() in container query arbitrary values. Let me do my best to explain why.

When it comes to media and container queries, order matters a lot, as the styles defined later in the CSS take precedence over those defined earlier. Tailwind uses this to it's advantage with it's mobile-first approach to responsive design, where larger screen size variants take precedence over smaller ones. You can read more about that here: https://tailwindcss.com/docs/responsive-design

Since Tailwind works this way, we automatically sort media queries (defined in your config) by their screen size — smallest to largest. However, if you happen to include raw media queries in your config, or if you're using mixed units (ie. both px and rem values), then we don't sort at all and simply use the order that the screens are defined in your config.

Further, if you use the min-* or max-* variants with an arbitrary value, you must use the same unit type (ie. px or rem) across all those variants and the screen sizes defined in your config, otherwise Tailwind is unable to sort these styles properly and will treat these arbitrary values as invalid and will throw them out.

You can read a detailed explanation of why it works this way here: tailwindlabs/tailwindcss#9558 (comment)

These exact same challenges exist with the container queries plugin. Yes, if you were writing raw CSS you could use calc() in your container queries, and then just make sure yourself that the styles are in the correct order. However, that's not possible for us to do in an automatic way, as we can't evaluate the calc() function, as this could be based on runtime information, such as the width of the element it's in, or the size of the viewport, or even a custom property.

We also can't rely on the order in which the container query variants are detected, as this can easily change depending on your content — as you add, remove or change files. And, even if that wasn't an issue, this would still very likely lead to the incorrect sorting of the container queries styles, as it would simply be based on what class was found first, and not based on smallest to largest values.

Further, since we're talking about arbitrary values here and not values from the config, we can't even rely on the order that they were defined in your config, as they don't exist there.

For all these reasons we currently throw away arbitrary container query sizes that we cannot sort:

(value = '', { modifier }) => {
let parsed = parseValue(value)
return parsed !== null ? `@container ${modifier ?? ''} (min-width: ${value})` : []

We technically could update this plugin to not do this, but then we'd, of course, have to decide how to sort these values, which there is no reliable way of doing. Here's an example Tailwind Play that does exactly this, which you're totally welcome to use, but you'll notice that the outputted CSS for the arbitrary container query sizes doesn't make sense:

https://play.tailwindcss.com/eaHjt6LxxS

So in conclusion, as far as I can tell, there just isn't a great way to support using calc() in arbitrary container query sizes, so I am going to close this issue for now.

I hope that explanation was helpful.

@reinink reinink closed this as completed Sep 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants