Media queries in CSS

Cover Image for Media queries in CSS
Ali Bentaleb
Ali Bentaleb

Media queries are queries that are used with HTML content, in which they are able to apply specific CSS content based on a matching query or queries, that way we can apply specific CSS to match devices such as tablets or smart phones or simply apply specific CSS to print the HTML page on A4 format for example. They are one of the features that makes responsive Web design, and they became W3C recommended standard since June 2012. Today the latest version is media queries level 5 as a working draft released on July 2020. We will be focusing on media queries level 4 as it is not much of a difference of level 4 which was released as a candidate recommendation on July 2020 also.

A **media query** is either **true or false**, it is true if:
  • Media type not specified, and media condition is true.
  • Or, media type is specified and it is matching the one where the user agent is running on.

Media queries syntax

We present below a sample to better understand how you can write media queries syntax in CSS.

```css @media all (max-width: 768px) { .divContainer p { display: flex; width: 100%; flex-direction: column; } } ```

We specify the media keyword preceded with '@' and specify the media type, whether it is 'all' keyword which will be applied to all sort of devices in the sample above, so for the HTML paragraph p which is contained in the divContainer class, the width will be set to 100%, the display will be set to flex and the direction will be set to column if the viewport of the device is less or equal 768px.

Tip: if the media type is all, we can simply omit this keyword as it the default value.

Media queries modifiers

There are two types of modifiers in media queries, which alter their meanings: not and only.

- _**not**_ to apply the contrary, like _@media not (screen) and (color)_, which means apply media on user agent or display device who does not have colored screens, for example print on paper with black and white. Not is applied to both not only screen.
  • only is used for legacy user agents, since they read the first non-alphanumeric on the media syntax and the rest is ignored, example: screen and (color), legacy agent would read screen, and ignore the rest, so to keep compatibility with older user agents, the keyword only is introduced so that older legacy user agents would not read anything, and new user agents ignore this keyword by default when it is the first, like only(screen) and (color), modern user agents would read the whole sentence while old agents will read only and do not apply anything, so the wanted behavior is to read everything or read nothing.

Evaluating media queries and error handling

Each media query is evaluated to a boolean result, either true of false, in case the query is not resolved, it is an unknown value and thus makes it false.

Combining media queries

Media queries can be combined using logical operators: and, or, not.

  • Two conditions can be chained together like (height>=500px) and (width<=200px).
  • Feature name which can be evaluated to Boolean can have not applied directly like, not(color).
  • Parentheses can be applied to two or more conditions, like (not (color) and (hover)) to specify monochrome screens with hover capabilities.

Media queries with import rule:

An example to show up the media query is to combine it with import-rule, we define our React component named MediaTypes, and we apply the divContainer class on it, and also the media query if the screen is less than 640px on which the display become _column_, we also define an import rule if only the orientation is portrait and the screen has color on it, in that case the display became _row_ instead of _column_ on screens of _max-width_ of 640px, so let's take a look:
import mediaStyles from "../styles/media.module.css";
const MediaTypes = () => {
  const cards = [
    { id: "1", name: "CSS, HTML", excerpt: "Start learning CSS, HTML" },
    {
      id: "2",

      name: "ES6 fundamentals",
      excerpt: "ES6 basics to fully understand JSX",
    },
    {
      id: "3",
      name: "React ",
      excerpt: "Start learning React, React hooks and others",
    },
    {

      id: "4",
      name: "Next.js",
      excerpt: "Next.js for better SEO and static generation",
    },
  ];

  return (
    <div className={mediaStyles.divContainer}>
      <CardContainer cards={cards} />

    </div>
  );
};

export default MediaTypes;

Our media.module.css is like:

.divContainer {
  display: flex;
  width: 100%;
}

@media (max-width: 640px) {
  .divContainer {
    display: flex;
    width: 100%;
    flex-direction: column;
  }
}
/* Order is important in a CSS file, this will apply last and be triggered only if orientation is portrait and screen has color*/
@import url(Home.module.css) (orientation: portrait) and (color);

And finally our Home.module.css:

@media (max-width: 640px) {
  .divContainer {
    display: flex;
    width: 100%;
    flex-direction: column;
  }
}

Media types

The most known media types are: all, print, screen, speech. Though CSS2.1 has introduced other media types that you can find more in depth in the W3C Media queries level 4, but all of them are deprecated in the media queries level 4 except for:

  • all: is suitable for most devices.
  • print: is suitable for printing pages or preview the page when is printed.
  • screen: is destined for screens.
  • speech: intended for speech synthesizers.

However, media types have created some kind of discrimination between devices, and some of them become deprecated over time like tty and tv. It is recommended to use the device aspect like width rather than specifying a kind of device.

Media features syntax

A media feature is a more specific testing tool to apply CSS to, which goes beyond media type and can be applied to specific device width for example.

Its syntax is always wrapped in parentheses, and can be combined with or , and, and is either:

  • (feature name : feature value) , like (orientation :landscape)
  • (feature name), when the media feature can be evaluated to false or true, like (color).
  • range form, which uses mathematical comparison operators instead of a colon, this is introduced in media queries level 4 so it is a new feature, or preceded with min or max values, like (max-width : 640px) or (width>=600px).

Prefix 'min-' is equivalent to use '>=' so (min-width : 600px) and (width >= 600px) are equivalent.

Prefix 'max-' is equivalent to '<=' so (max-width : 600px) and (width <= 600px) are equivalent.

Deprecated media features

Some of the deprecated media features are: device-width, device-height and device-aspect-ratio, though they are still supported for backward compatibility, but for any future use consider not using these anymore.

Media queries with tailwindcss

Tailwindcss offers great capability and ease of use of media queries, one of the fundamentals to use media queries with tailwindcss is to think mobile first, which means most of the media queries provided are for larger screen scales and the default CSS is applied to mobile, let's see this example to understand more:


.privacyClass {
  /* this means that for screens larger than 768px, apply a max-width of 64rem;
  @apply  md:max-w-5xl;
}

So most keywords are used to mean larger screens and not apply to small screens like @media(max-width:600 px) would be used if we want to apply specific CSS to smaller screens.

There are also some other predefined sizes like sm for screens larger than 640px, lg for screens larger than 1024px and so on, you can find more details about screen sizes in tailwind responsive design.

Customizing tailwindcss for specific media queries

It is also possible to customize tailwindcss if you have specific need which is not covered by the predefined values, all you have to do is to edit the tailwind.config.js file, for example customizing the screen orientation.

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      screens: {
        landscape: { raw: "(orientation: landscape)" },
        // => @media (orientation: landscape) { ... }
      },
    },
  },
};

Now you can call it directly in any class with typing landscape.

How to easily add a new font t...