Media queries
Cacao provides a number of different media query variables that you can use in your code.
The media query variables use @custom-media
. Because @custom-media
is not yet supported the custom media PostCSS plugin is required as part of your build process.
Media query variables have the following naming conventions:
- The prefix
--m-
is used to indicate that these are media queries. - The variable must be all lowercase.
These are almost always included in a project along with the base styles and the reset styles.
How to import into your CSS
Import this into your CSS with:
@import 'cacao-css/dist/media.css';
Typically this is included above other styles.
See Import Cacao CSS for more information.
How to use the media query variables
To use the media query variables you could put them within the @media
declaration. For example, say that you want to use the large viewport media query, you can do something like this:
@media(--m-lg) {
.someSelector {
width: 50%;
}
}
Viewport media queries
The viewport sizes are:
Size | Viewport pixel width | Variable | "Below" variable | "Only" variable |
---|---|---|---|---|
3xs | 240px | --m-3xs | --m-3xs-below | --m-3xs-only |
2xs | 360px | --m-2xs | --m-2xs-below | --m-2xs-only |
xs | 420px | --m-xs | --m-xs-below | --m-xs-only |
sm | 576px | --m-sm | --m-sm-below | --m-sm-only |
md | 768px | --m-md | --m-md-below | --m-md-only |
lg | 1024px | --m-lg | --m-lg-below | --m-lg-only |
xl | 1280px | --m-xl | --m-xl-below | --m-xl-only |
2xl | 1440px | --m-2xl | --m-2xl-below | --m-2xl-only |
3xl | 1600px | --m-3xl | --m-3xl-below | --m-3xl-only |
4xl | 1920px | --m-4xl | --m-4xl-below | --m-4xl-only |
5xl | 2560px | --m-5xl | --m-5xl-below | --m-5xl-only |
The media queries are "mobile first" meaning they target screen widths larger than the specified viewport pixel width. For example, the sm
size targets screens larget than 576px.
@custom-media --m-sm (width >= 576px);
Each size also has a below
and an only
version.
The below
version is used to target this screen width and below. It's not a "mobile-first" media query.
@custom-media --m-sm-below (width < 576px);
The only
version is used to target the pixel range between this size and the size below it (or 0
if it's the 3xs size). For example, for the sm
size
@custom-media --m-sm-only (360px <= width < 576px);
Accessibility preferences
These are used to identify the user's browser preferences for motion and transparency.
@custom-media --m-motion-ok (prefers-reduced-motion: no-preference);
@custom-media --m-motion-not-ok (prefers-reduced-motion: reduce);
@custom-media --m-opacity-ok (prefers-reduced-transparency: no-preference);
@custom-media --m-opacity-not-ok (prefers-reduced-transparency: reduce);
Data preferences
These are used to identify the user's browser preferences around data (typically cellular data usage).
/* Data preferences */
@custom-media --m-use-data-ok (prefers-reduced-data: no-preference);
@custom-media --m-use-data-not-ok (prefers-reduced-data: reduce);
Color preferences
These are used to identify the user's browser preferences around colors.
@custom-media --m-dark (prefers-color-scheme: dark);
@custom-media --m-light (prefers-color-scheme: light);
@custom-media --m-high-contrast (prefers-contrast: more);
@custom-media --m-low-contrast (prefers-contrast: less);
@custom-media --m-inverted-colors (inverted-colors: inverted);
@custom-media --m-forced-colors (forced-colors: active);
Orientation
These are used to identify the user's browser preferences around device orientation.
@custom-media --m-portrait (orientation: portrait);
@custom-media --m-landscape (orientation: landscape);
Pointer types
These are used to help identify the pointer type used with the device.
@custom-media --m-touch (hover: none) and (pointer: coarse);
@custom-media --m-stylus (hover: none) and (pointer: fine);
@custom-media --m-pointer (hover) and (pointer: coarse);
@custom-media --m-mouse (hover) and (pointer: fine);
Color capabilities
These are used to identify the color capabilities of the defice.
@custom-media --m-hd-color (dynamic-range: high) or (color-gamut: p3);
Source CSS
Below is the full source for the media queries.
/* =========================================================================== *\
Custom media queries.
Because @custom-media is not yet supported a PostCSS plugin is required.
https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-media
Naming conventions:
- The prefix --m- is used to indicate that these are media queries.
- The variable must be all lowercase.
\* =========================================================================== */
/* Accessibility preferences */
@custom-media --m-motion-ok (prefers-reduced-motion: no-preference);
@custom-media --m-motion-not-ok (prefers-reduced-motion: reduce);
@custom-media --m-opacity-ok (prefers-reduced-transparency: no-preference);
@custom-media --m-opacity-not-ok (prefers-reduced-transparency: reduce);
/* Data preferences */
@custom-media --m-use-data-ok (prefers-reduced-data: no-preference);
@custom-media --m-use-data-not-ok (prefers-reduced-data: reduce);
/* Color preferences */
@custom-media --m-dark (prefers-color-scheme: dark);
@custom-media --m-light (prefers-color-scheme: light);
@custom-media --m-high-contrast (prefers-contrast: more);
@custom-media --m-low-contrast (prefers-contrast: less);
@custom-media --m-inverted-colors (inverted-colors: inverted);
@custom-media --m-forced-colors (forced-colors: active);
/* Orientation */
@custom-media --m-portrait (orientation: portrait);
@custom-media --m-landscape (orientation: landscape);
/* Pointer types */
@custom-media --m-touch (hover: none) and (pointer: coarse);
@custom-media --m-stylus (hover: none) and (pointer: fine);
@custom-media --m-pointer (hover) and (pointer: coarse);
@custom-media --m-mouse (hover) and (pointer: fine);
/* Color capabilities */
@custom-media --m-hd-color (dynamic-range: high) or (color-gamut: p3);
/**
* Screen sizes
*
* These breakpoints are inspired by:
* - Pure.(https://purecss.io/grids/#:~:text=%3C/div%3E-,Default%20Media%20Queries,-When%20using%20Responsive)
* - Bootstrap (https://getbootstrap.com/docs/5.3/layout/breakpoints/#available-breakpoints)
* - Open Props (https://open-props.style/#media-queries)
* - https://gs.statcounter.com/screen-resolution-stats/mobile/worldwide
* - https://www.browserstack.com/guide/common-screen-resolutions
* - And our own usage in building websites
*
* Cacao is a mobile-first system.
* We don't use min-width or max-width because we follow Stylelint's media-feature-range-notation rule.
* https://stylelint.io/user-guide/rules/media-feature-range-notation/
*
* We use pixels instead of ems because that is the convention and it helps prevent a Safari bug with how they calculate ems (i.e. they use font-size + zoom level)
* https://cgamesplay.com/post/2023/05/19/stop-using-em-in-media-queries/
*
* https://www.joshwcomeau.com/css/surprising-truth-about-pixels-and-accessibility/ is another viewpoint on this and considers users increacing the default
* font size in their browser settings. Need to explore this more. 10/26/2024
*/
/* 3xs */
@custom-media --m-3xs (width >= 240px);
@custom-media --m-3xs-below (width < 240px);
@custom-media --m-3xs-only (0 <= width < 240px);
/* 2xs */
@custom-media --m-2xs (width >= 360px);
@custom-media --m-2xs-below (width < 300px);
@custom-media --m-2xs-only (0 <= width < 300px);
/* xs */
@custom-media --m-xs (width >= 420px);
@custom-media --m-xs-below (width < 420px);
@custom-media --m-xs-only (300px <= width < 420px);
/* sm */
@custom-media --m-sm (width >= 576px);
@custom-media --m-sm-below (width < 576px);
@custom-media --m-sm-only (360px <= width < 576px);
/* md */
@custom-media --m-md (width >= 768px);
@custom-media --m-md-below (width < 768px);
@custom-media --m-md-only (576px <= width < 768px);
/* lg */
@custom-media --m-lg (width >= 1024px);
@custom-media --m-lg-below (width < 1024px);
@custom-media --m-lg-only (768px <= width < 1024px);
/* xl */
@custom-media --m-xl (width >= 1280px);
@custom-media --m-xl-below (width < 1280px);
@custom-media --m-xl-only (1024px <= width < 1280px);
/* 2xl */
@custom-media --m-2xl (width >= 1440px);
@custom-media --m-2xl-only (1280px <= width < 1440px);
@custom-media --m-2xl-below (width < 1440px);
/* 3xl */
@custom-media --m-3xl (width >= 1600px);
@custom-media --m-3xl-only (1440px <= width < 1600px);
@custom-media --m-3xl-below (width < 1600px);
/* 4xl */
@custom-media --m-4xl (width >= 1920px);
@custom-media --m-4xl-only (1600px <= width < 1920px);
@custom-media --m-4xl-below (width < 1920px);
/* 5xl */
@custom-media --m-5xl (width >= 2560px);
@custom-media --m-5xl-only (1920px <= width < 2560px);
@custom-media --m-5xl-below (width < 2560px);