GitHunt
YU

yunusga/postcss-sort-media-queries

PostCSS plugin for sorting and combining CSS media queries with mobile-first / desktop-first methodologies.

PostCSS Sort Media Queries

npm Node.js CI
license
npm

🌏 EnglishO'zbek

PostCSS plugin for sorting and combining CSS media queries with mobile first / desktop first methodologies.

From v6.0.0 plugin supported nested media queries and ESM usage

Table of Contents

Online demo

And here is the Online Demo

Examples

Mobile first sorting

Before

@media (min-width: 1400px) {}
@media (min-width: 1200px) {}

@layer reset {

  @media (min-width: 1200px) {
    @media (min-width: 992px) {}
    @media (min-width: 768px) {}
  }

  @media (min-width: 768px) {
    @media (min-width: 640px) {}
    @media (min-width: 320px) {}
  }
}

After

@layer reset {

  @media (min-width: 768px) {
    @media (min-width: 320px) {}
    @media (min-width: 640px) {}
  }

  @media (min-width: 1200px) {
    @media (min-width: 768px) {}
    @media (min-width: 992px) {}
  }
}

@media (min-width: 1200px) {}
@media (min-width: 1400px) {}

Desktop first sorting

Before

@media screen and (width < 640px) {
  .header { color: #cdcdcd }
}
@media screen and (min-width: 760px) {
  .desktop-first { color: #cdcdcd }
}
@media screen and (width < 640px) {
  .main { color: #cdcdcd }
}
@media screen and (min-width: 1280px) {
  .desktop-first { color: #cdcdcd }
}
@media screen and (max-width: 760px) {
  .footer { color: #cdcdcd }
}
@media screen and (max-width: 640px) {
  .footer { color: #cdcdcd }
}

After

@media screen and (max-width: 760px) {
  .footer { color: #cdcdcd }
}
@media screen and (width < 640px) {
  /* combined */
  .header { color: #cdcdcd }
  .main { color: #cdcdcd }
  .footer { color: #cdcdcd }
}
@media screen and (min-width: 760px) {
  .desktop-first { color: #cdcdcd }
}
@media screen and (min-width: 1280px) {
  .desktop-first { color: #cdcdcd }
}

Nested media queries sorting

Before

@media (min-width: 710px) {
  .print-only-global-2 {
    display: block;
  }
}

@media (min-width: 1210px) {
  .print-only-global-4 {
    display: block;
  }

  .print-only-global-5 {
    display: block;
  }

  .print-only-global-6 {
    display: block;
  }
}

@media (min-width: 310px) {
  .print-only-global-1 {
    display: block;
  }
}

@media (min-width: 710px) {
  .print-only-global-3 {
    display: block;
  }
}

@media (min-width: 1210px) {
  .print-only-global-7 {
    display: block;
  }
}

@media print {
  .print-only {
    display: block;
  }

  .print-only-parent-1 {
    display: block;
  }

  @media (orientation: landscape) {
    .print-only {
      color: black;
    }

    @media (min-width: 910px) {
      .nested-landscape-3 {
        color: black;
      }

      .nested-landscape-4 {
        color: black;
      }

      .nested-landscape-5 {
        color: black;
      }
    }

    @media (min-width: 810px) {
      .nested-landscape-2 {
        color: black;
      }
    }

    @media (min-width: 710px) {
      .nested-landscape-1 {
        color: black;
      }
    }

    .nested-landscape-0 {
      color: black;
    }

    @media (min-width: 710px) {
      .nested-landscape-4 {
        color: black;
      }

      .nested-landscape-5 {
        color: black;
      }

      .nested-landscape-6 {
        color: black;
      }
    }

    @media (min-width: 710px) {
      .nested-landscape-8 {
        color: black;
      }

      .nested-landscape-9 {
        color: black;
      }
    }
  }

  @media (min-width: 500px) {
    .print-only {
      color: black;
    }
  }

  .print-only-parent-2 {
    display: block;
  }

  @media (min-width: 500px) {
    .print-only {
      color: black;
    }
  }

  @media (orientation: portrait) {
    .print-only {
      color: gray;
    }
  }

  .print-only-parent-3 {
    display: block;
  }

  @media (min-width: 320px) {
    .print-only {
      color: black;
    }
  }

  @media (orientation: landscape) {
    .print-only-landscape-1-1 {
      color: gray;
    }

    .print-only-landscape-1-2 {
      color: gray;
    }

    .print-only-landscape-1-3 {
      color: gray;
    }
  }
}

@layer base {

  @media (min-width: 1220px) {
    .print-only-1200-1 {
      color: black;
    }
  }

  @media (min-width: 320px) {
    .print-only-320-1 {
      color: black;
    }
  }

  @media (min-width: 1220px) {
    .print-only-1200-2 {
      color: black;
    }
  }

  @media (min-width: 620px) {
    .print-only-640-1 {
      color: black;
    }
  }

  @media (min-width: 320px) {
    .print-only-320-2 {
      color: black;
    }
  }

  @media (min-width: 320px) {
    .print-only-320-3 {
      color: black;
    }
  }

  @media (min-width: 620px) {
    .print-only-640-2 {
      color: black;
    }
  }
}

After

@layer base {
  @media (min-width: 320px) {
    .print-only-320-1 {
      color: black;
    }
    .print-only-320-2 {
      color: black;
    }
    .print-only-320-3 {
      color: black;
    }
  }
  @media (min-width: 620px) {
    .print-only-640-1 {
      color: black;
    }
    .print-only-640-2 {
      color: black;
    }
  }
  @media (min-width: 1220px) {
    .print-only-1200-1 {
      color: black;
    }
    .print-only-1200-2 {
      color: black;
    }
  }
}
@media (min-width: 310px) {
  .print-only-global-1 {
    display: block;
  }
}
@media (min-width: 710px) {
  .print-only-global-2 {
    display: block;
  }
  .print-only-global-3 {
    display: block;
  }
}
@media (min-width: 1210px) {
  .print-only-global-4 {
    display: block;
  }

  .print-only-global-5 {
    display: block;
  }

  .print-only-global-6 {
    display: block;
  }
  .print-only-global-7 {
    display: block;
  }
}
@media print {
  .print-only {
    display: block;
  }

  .print-only-parent-1 {
    display: block;
  }

  .print-only-parent-2 {
    display: block;
  }

  .print-only-parent-3 {
    display: block;
  }

  @media (min-width: 320px) {
    .print-only {
      color: black;
    }
  }

  @media (min-width: 500px) {
    .print-only {
      color: black;
    }
    .print-only {
      color: black;
    }
  }

  @media (orientation: landscape) {
    .print-only {
      color: black;
    }

    .nested-landscape-0 {
      color: black;
    }
    .print-only-landscape-1-1 {
      color: gray;
    }

    .print-only-landscape-1-2 {
      color: gray;
    }

    .print-only-landscape-1-3 {
      color: gray;
    }

    @media (min-width: 710px) {
      .nested-landscape-1 {
        color: black;
      }
      .nested-landscape-4 {
        color: black;
      }

      .nested-landscape-5 {
        color: black;
      }

      .nested-landscape-6 {
        color: black;
      }
      .nested-landscape-8 {
        color: black;
      }

      .nested-landscape-9 {
        color: black;
      }
    }

    @media (min-width: 810px) {
      .nested-landscape-2 {
        color: black;
      }
    }

    @media (min-width: 910px) {
      .nested-landscape-3 {
        color: black;
      }

      .nested-landscape-4 {
        color: black;
      }

      .nested-landscape-5 {
        color: black;
      }
    }
  }

  @media (orientation: portrait) {
    .print-only {
      color: gray;
    }
  }
}

Install

First thing's, install the module:

npm install postcss postcss-sort-media-queries --save-dev

Usage

Check you project for existed PostCSS config: postcss.config.js
in the project root, "postcss" section in package.json
or postcss in bundle config.

// CJS
let sortCssMq = require('postcss-sort-media-queries');

// ESM
import sortCssMq from 'postcss-sort-media-queries';

If you already use PostCSS, add the plugin to plugins list:

module.exports = {
  plugins: [
+   require('postcss-sort-media-queries')({
+     sort: 'mobile-first', // default value
+   }),
    require('autoprefixer')
  ]
}

or with custom sort function

module.exports = {
  plugins: [
+   require('postcss-sort-media-queries')({
+     sort: function(a, b) {
+        // custom sorting function
+     }
+   }),
    require('autoprefixer')
  ]
}

If you do not use PostCSS, add it according to official docs
and set this plugin in settings.

Options

Sorting works based on OlehDutchenko/sort-css-media-queries function.

sort

This option support string or function values.

  • {string} 'mobile-first' - (default) mobile first sorting
  • {string} 'desktop-first' - desktop first sorting
  • {function} your own sorting function

'mobile-first'

postcss([
  sortMediaQueries({
    sort: 'mobile-first' // default
  })
]).process(css);

'desktop-first'

postcss([
  sortMediaQueries({
    sort: 'desktop-first'
  })
]).process(css);

Custom sort function

postcss([
  sortMediaQueries({
    function(a, b) {
      return a.localeCompare(b);
    }
  })
]).process(css);

In this example, all your media queries will sort by A-Z order.

This sorting function is directly passed to Array#sort() method of an array of all your media queries.

Sort configuration

By this configuration you can control sorting behaviour.

postcss([
  sortMediaQueries({
    configuration: {
      unitlessMqAlwaysFirst: true, // or false
    }
  })
]).process(css);

Or alternatively create a sort-css-mq.config.json file in the root of your project. Or add property sortCssMQ: {} in your package.json.


Changelog

See Releases history

License

MIT

Other PostCSS plugins

  • postcss-momentum-scrolling - plugin for adding momentum style scrolling behavior (-webkit-overflow-scrolling:touch) for elements with overflow (scroll, auto) on iOS

Thanks

yunusga/postcss-sort-media-queries | GitHunt