postcss-sort-media-queries
postcss-sort-media-queries copied to clipboard
Problem with Nested media queries
Hi!
It think that I found problem in this plugin. CSS allows nesting at-rules. The plugin ignores this.
Problem
Minimum code example:
import postcss from 'postcss';
import sortMediaQueries from 'postcss-sort-media-queries';
let style = `
@media (min-width: 700px) {
.a {
color: #00FF00;
}
}
@media print {
@media (min-width: 700px) {
.b {
color: #FF0000;
}
}
}
`;
postcss([
sortMediaQueries({
sort: 'mobile-first'
})
])
.process(style)
.then(function(result) {
console.log(result.css);
});
Result:
@media (min-width: 700px) {
.a {
color: #00FF00;
}
.b {
color: #FF0000;
}
}
@media print {
@media (min-width: 700px) {
.b {
color: #FF0000;
}
}
}
But the code shouldn't have changed. It's my case and I solved it with option in postcss-preset-env
features: {
'nesting-rules': true
}
My solution won't help with other at-rules. For example:
@media (min-width: 700px) {
.a {
color: #00FF00;
}
}
@supports (animation-name: test) {
@media (min-width: 700px) {
.b {
color: #FF0000;
}
}
}
My environment:
- node v14.16.1
- npm 7.19.1
- postcss: "8.3.5"
- postcss-sort-media-queries: "3.11.12"
I can confirm this is an issue. Here is the code example where the sorting logic fails:
@custom-media --breakpoint-sm (min-width: 600px);
@custom-media --hover-check (hover: hover);
.link {
color: blue;
@media (--hover-check) {
&:hover {
color: red;
}
}
@media (--breakpoint-sm) {
color: green;
@media (--hover-check) {
&:hover {
color: pink;
}
}
}
}
Which results to:
.link {
color: blue;
}
@media (min-width: 600px){
.link {
color: green
}
@media (hover: hover) {
.link:hover {
color: pink;
}
}
}
@media (hover: hover){
.link:hover {
color: red;
}
.link:hover {
color: pink;
}
}
Instead of:
.link {
color: blue;
}
@media (hover: hover) {
.link:hover {
color: red;
}
}
@media (min-width: 600px) {
.link {
color: green
}
@media (hover: hover) {
.link:hover {
color: pink;
}
}
}
@iamskok need your configuration because i have different result for your example without sorting
@media (min-width: 600px) and (hover: hover)
Result without sorting
.link {
color: blue;
}
@media (hover: hover) {
.link:hover {
color: red;
}
}
@media (min-width: 600px) {
.link {
color: green;
}
}
@media (min-width: 600px) and (hover: hover) {
.link:hover {
color: pink;
}
}
Hi @yunusga, I also have a repro of this issue: https://codesandbox.io/s/postcss-forked-vw07gs?file=/src/index.js:102-192.
Input:
@supports(container-type:inline-size) {
@media(min-width: 300px) {
color: red;
}
}
Output:
@supports(container-type:inline-size) {
}
@media (min-width: 300px) {
color: red
}
Expected output (same as input):
@supports(container-type:inline-size) {
@media(min-width: 300px) {
color: red;
}
}
Hi @jimmy-guo, thanks, yes, that's right, I am aware of this problem, I will add an update soon. I didn't do this functionality because Firefox still doesn't support it https://caniuse.com/css-nesting
Linked issue https://github.com/OlehDutchenko/sort-css-media-queries/issues/24
@iamskok, @jimmy-guo, @pavel-klimov I added quick fix for problem with ejected nested media queries postcss-sort-media-queries/blob/v5.2.0/README.md#only-top-level