postcss-sort-media-queries icon indicating copy to clipboard operation
postcss-sort-media-queries copied to clipboard

Problem with Nested media queries

Open pavel-klimov opened this issue 3 years ago • 6 comments

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"

pavel-klimov avatar Jul 07 '21 15:07 pavel-klimov

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 avatar Oct 24 '22 04:10 iamskok

@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;
  }
}

yunusga avatar Oct 26 '22 06:10 yunusga

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;
  }
}

jimmy-guo avatar May 25 '23 22:05 jimmy-guo

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 avatar May 26 '23 01:05 yunusga

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

yunusga avatar May 30 '23 07:05 yunusga

@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

yunusga avatar May 30 '23 13:05 yunusga