# Media Queries

> Part of mCSS (mcss.dev). Rendered page: https://mcss.dev/docs/media-queries

| File name                    | Source        |
| ---------------------------- | ------------- |
| `settings.media-queries.css` | [Github][src] |

[src]: https://github.com/minimaldesign/mCSS/blob/main/src/styles/framework/settings.media-queries.css

<Notice
  type="info"
  title="PostCSS needed for custom media queries"
  class="mt-sm3 mb-sm3"
>
  [Custom media queries][custom] are not yet available without a [PostCSS
  plugins][postcss]. If you can't or don't want to add a build step to your
  process, you'll have to hard code your breakpoints. (You can still use nesting
  as in the example below though.)
</Notice>

## Viewport size

### Dimensions

<div class="docs_oversizedTable">

| Token keyword | Dimension (px) |
| ------------- | -------------- |
| `xxs`         | 0-240          |
| `xs`          | 240-360        |
| `sm`          | 360-480        |
| `md`          | 480-768        |
| `lg`          | 768-1024       |
| `xl`          | 1024-1440      |
| `xxl`         | 1440-1920      |

</div>

### Variations

Using the `md` dimension as an example:

<div class="docs_oversizedTable">

| Token variation | Matches                      |
| --------------- | ---------------------------- |
| `--md-only`     | exact range                  |
| `--md-n-above`  | range top and above          |
| `--md`          | shorthand for `--md-n-above` |
| `--md-n-below`  | range top and below          |
| `--md-phone`    | exact range in portrait only |

</div>

### Examples

<div class="docs_oversizedTable">

| Custom media query        | Value                           |
| ------------------------- | ------------------------------- |
| `@media(--md-only) {}`    | `(480px <= width < 768px);`     |
| `@media(--md) {}`         | `(width >= 768px);`             |
| `@media(--md-n-above) {}` | `(width >= 768px);`             |
| `@media(--md-n-below) {}` | `(width < 768px);`              |
| `@media(--md-phone) {}`   | `(--md-only) and (--portrait);` |

</div>

The `-phone` variant is available from `xxs` through `lg` (there is no `xl-phone` or `xxl-phone`).

### Recommended responsive setup

If you search online for the best approach to responsive design and setting up your breakpoints, you'll come across the technically true but useless "it depends" answer.

Unless you have a good reason not to, you should use a mobile first approach. What that means is your design will work great on small screens out of the box, without any media queries, and then you add your tweaks for additional sizes.

This is how the CSS of most responsive components should be set up:

```css
.exampleComponent {
  /* default mobile */
  @media (--lg) {
    /* responsive tweaks for desktop */
  }
}
```

Without [PostCSS plugins][postcss]:

```css
.exampleComponent {
  /* default mobile */
  @media (width >= 1024px) {
    /* responsive tweaks for desktop */
  }
}
```

## User preferences

These map to the `prefers-*` and related media features, so you can respect user settings without memorizing the syntax:

<div class="docs_oversizedTable">

| Custom media query | Matches                                         |
| ------------------ | ----------------------------------------------- |
| `--motionOK`       | `(prefers-reduced-motion: no-preference)`       |
| `--motionNotOK`    | `(prefers-reduced-motion: reduce)`              |
| `--opacityOK`      | `(prefers-reduced-transparency: no-preference)` |
| `--opacityNotOK`   | `(prefers-reduced-transparency: reduce)`        |
| `--useDataOK`      | `(prefers-reduced-data: no-preference)`         |
| `--useDataNotOK`   | `(prefers-reduced-data: reduce)`                |
| `--OSdark`         | `(prefers-color-scheme: dark)`                  |
| `--OSlight`        | `(prefers-color-scheme: light)`                 |
| `--highContrast`   | `(prefers-contrast: more)`                      |
| `--lowContrast`    | `(prefers-contrast: less)`                      |
| `--invertedColors` | `(inverted-colors: inverted)`                   |
| `--forcedColors`   | `(forced-colors: active)`                       |

</div>

## Device capabilities

<div class="docs_oversizedTable">

| Custom media query | Matches                                      |
| ------------------ | -------------------------------------------- |
| `--portrait`       | `(orientation: portrait)`                    |
| `--landscape`      | `(orientation: landscape)`                   |
| `--HDcolor`        | `(dynamic-range: high) or (color-gamut: p3)` |
| `--touch`          | `(hover: none) and (pointer: coarse)`        |
| `--stylus`         | `(hover: none) and (pointer: fine)`          |
| `--pointer`        | `(hover) and (pointer: coarse)`              |
| `--mouse`          | `(hover) and (pointer: fine)`                |

</div>

### Example

These are used like any other custom media query, and they can be combined with each other or with a dimension token:

```css
.exampleComponent {
  @media (--landscape) and (--touch) {
    /* a phone or tablet held sideways */
  }
}
```

Without [PostCSS plugins][postcss], the same thing spelled out:

```css
.exampleComponent {
  @media (orientation: landscape) and ((hover: none) and (pointer: coarse)) {
    /* a phone or tablet held sideways */
  }
}
```

[custom]: https://drafts.csswg.org/mediaqueries-5/#custom-mq
[postcss]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-media
