yunusga / postcss-sort-media-queries

PostCSS plugin for sorting and combining CSS media queries with mobile-first / desktop-first methodologies.
https://postcss-sort-media-queries.github.io
MIT License
144 stars 7 forks source link

Problem with Nested media queries #38

Open pavel-klimov opened 2 years ago

pavel-klimov commented 2 years ago

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:

iamskok commented 1 year ago

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;
    }
  }
}
yunusga commented 1 year ago

@iamskok need your configuration because i have different result for your example without sorting

@media (min-width: 600px) and (hover: hover)

Result without sorting ```css .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; } } ```
jimmy-guo commented 1 year ago

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;
  }
}
yunusga commented 1 year ago

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

yunusga commented 1 year ago

Linked issue https://github.com/OlehDutchenko/sort-css-media-queries/issues/24

yunusga commented 1 year ago

@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