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

Media query range gap not calculated correctly #864

Closed
niksy opened this issue Dec 5, 2024 · 5 comments
Closed

Media query range gap not calculated correctly #864

niksy opened this issue Dec 5, 2024 · 5 comments

Comments

@niksy
Copy link

niksy commented Dec 5, 2024

Consider the following CSS:

@media screen and (width >= 1024px) {
  body {
    background: red;
  }
}
@media screen and (width < 1024px) {
  body {
    background: blue;
  }
}

What is expected here (when using syntax which is not syntax lowered to min-width and max-width equivalents) is that body will have blue background color on screen width less than 1024px, but anything equal or larger than that gets red background color.

Lightning CSS transforms this to following CSS (playground):

@media screen and (min-width: 1024px) {
  body {
    background: red;
  }
}

@media screen and (max-width: 1024px) {
  body {
    background: #00f;
  }
}

This results in blue background color even in 1024px screen width. Reshuffling ranges so that "lower than" is above is one solution but that can result in specificity bugs and is not quite advisable in any non-trivial codebase.

What I noticed is that this happens on values larger than 1000px, anything lower than that produces valid code. This is even covered in test case.

Same query gets properly transformed with "value gap" using PostCSS and syntax lowering plugin (playground).

If I’m understanding correctly, this is covered with steps depending on which range identifier is requested.

This is known as double breakpoint bug and is common issue if codebase contains ranges which overlap. The issue gets even more complex when using values other than pixels since calculations are slightly different.

@fregante
Copy link

fregante commented Dec 9, 2024

In the past I resolved this by using not

@media screen and (width < 1024px)

becomes

@media screen and not (min-width: 1024px)

This is an exact boolean equivalent and does not rely on rounding/steps.

@niksy
Copy link
Author

niksy commented Dec 9, 2024

Interesting, haven’t thought about that, but since rounding/steps approach is already implemented and known as a solution, maybe still go with this?

I’m wondering what could be the reason why this doesn’t work with values larger than 1000px. I don’t see anyhing related to this, maybe it’s that calculations on Rust side work differently?

@devongovett
Copy link
Member

Thanks for the suggestion, @fregante! The above commit implements this. The input in the original issue now compiles to:

@media screen and (min-width: 1024px) {
  body {
    background: red;
  }
}

@media screen and not (min-width: 1024px) {
  body {
    background: #00f;
  }
}

@LeoniePhiline
Copy link
Contributor

@niksy

I’m wondering what could be the reason why this doesn’t work with values larger than 1000px. I don’t see anyhing related to this, maybe it’s that calculations on Rust side work differently?

I case you are still interested in the details, you can read them here: #228 (comment)

@niksy
Copy link
Author

niksy commented Dec 22, 2024

Thanks for this! And it seems like approach by @fregante solved a lot of other situations where fraction calculation was used :)

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