CSS @media At-Rule

The @media at-rule applies CSS styles only when specified media conditions are met. It is commonly used to create responsive layouts, adjust styles for printing, detect device capabilities, and accommodate user preferences such as dark mode and reduced motion.

@media Syntax

@media media-query {
  selector {
    property: value;
  }
}

The @media at-rule begins with a media query followed by a block containing CSS rules. The rules apply only when the media query evaluates to true.

@media (max-width: 600px) {
  .container {
    padding: 10px;
  }
}

This example applies 10px padding when the viewport is 600 pixels wide or narrower.

A media query can contain a media type, one or more media features, and logical operators.

How @media Works

The browser evaluates the condition in a media query and applies its CSS declarations when the condition matches the current environment.

.box {
  background-color: #0056b3;
}
@media (max-width: 600px) {
  .box {
    background-color: #198754;
  }
}

The box has a blue background when the viewport is wider than 600 pixels. At 600 pixels or narrower, its background becomes green.

Media queries are evaluated as the environment changes. For example, resizing the browser window can cause a width-based query to start or stop matching.

Declarations inside a matching @media block still follow the normal CSS cascade, including specificity, importance, and source order.

Media Types

Media types identify the general category of output for which CSS styles are intended.

Media Type Description
all Matches all media types.
screen Targets screen-based displays.
print Targets printed documents and print previews.

Screen Styles

@media screen {
  body {
    background-color: #f5f5f5;
  }
}

Print Styles

@media print {
  body {
    background-color: #fff;
    color: #000;
  }
}

The media type can be omitted when a query only needs to test media features. In that case, all is implied.

Older media types such as handheld, projection, and tv are deprecated and should not be used for modern responsive layouts.

Media Features

Media features test characteristics of the viewport, output device, input capabilities, or user environment.

Media Feature Description
width Tests the viewport width.
height Tests the viewport height.
orientation Tests whether the viewport is portrait or landscape.
aspect-ratio Tests the viewport width-to-height ratio.
resolution Tests the output device's pixel density.
hover Tests whether the primary input mechanism can hover.
pointer Tests the accuracy of the primary pointing device.
prefers-color-scheme Tests the user's light or dark color scheme preference.
prefers-reduced-motion Tests whether the user prefers reduced motion.
prefers-contrast Tests the user's contrast preference.

Viewport Orientation

@media (orientation: landscape) {
  .layout {
    flex-direction: row;
  }
}

This rule applies when the viewport is wider than it is tall.

Hover Capability

@media (hover: hover) {
  .button:hover {
    background-color: #003d80;
  }
}

This applies a hover style when the primary input mechanism supports convenient hovering.

Responsive Breakpoints

Breakpoints are conditions where a layout changes to accommodate the available space. Media queries commonly use min-width and max-width to define these conditions.

Mobile-First Approach

A mobile-first approach starts with styles for narrower viewports and adds changes as more space becomes available.

.layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 15px;
}
@media (min-width: 768px) {
  .layout {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 1024px) {
  .layout {
    grid-template-columns: repeat(3, 1fr);
  }
}

The layout uses one column below 768 pixels, two columns from 768 pixels, and three columns from 1024 pixels.

Desktop-First Approach

A desktop-first approach begins with wider layouts and modifies them as the viewport becomes narrower.

.layout {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 767px) {
  .layout {
    grid-template-columns: 1fr;
  }
}

Neither approach requires fixed device-specific breakpoints. Choose breakpoint values based on when the content and layout need to change.

Range Syntax

Modern media queries support comparison operators for testing range-based features such as width and height.

Minimum Width

@media (width >= 768px) {
  .container {
    max-width: 720px;
  }
}

This is equivalent to using (min-width: 768px).

Maximum Width

@media (width <= 600px) {
  .container {
    padding: 10px;
  }
}

This is equivalent to using (max-width: 600px).

Between Two Widths

@media (600px <= width <= 1000px) {
  .container {
    max-width: 900px;
  }
}

This query matches viewport widths from 600 through 1000 pixels, including both endpoints.

The operators < and > exclude the specified boundary values, while <= and >= include them.

Logical Operators

Logical operators combine or modify media query conditions.

Operator Description
and Requires all combined conditions to match.
not Negates a media query or supported media condition.
or Matches when at least one combined condition matches.
, Separates media queries into a list where any matching query is sufficient.
only Provides a legacy compatibility safeguard for media-type queries.

Using and

@media screen and (min-width: 768px) {
  .sidebar {
    display: block;
  }
}

Both conditions must match: the media type must be screen, and the viewport must be at least 768 pixels wide.

Using a Comma

@media (max-width: 600px), (orientation: portrait) {
  .box {
    padding: 10px;
  }
}

The styles apply when either condition matches.

Using not

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

This matches media types other than print.

Using only

@media only screen and (min-width: 768px) {
  .container {
    max-width: 720px;
  }
}

The only keyword was introduced to prevent certain older browsers from incorrectly applying media queries. It is generally unnecessary for modern browsers.

User Preferences

Some media features allow CSS to respond to accessibility and appearance preferences configured in the user's operating system or browser.

Dark Mode

@media (prefers-color-scheme: dark) {
  body {
    background-color: #222;
    color: #fff;
  }
}

This applies dark colors when the user prefers a dark color scheme.

Reduced Motion

.panel {
  transition: transform 0.3s ease;
}
@media (prefers-reduced-motion: reduce) {
  .panel {
    transition: none;
  }
}

This removes the panel's transition when the user requests reduced motion.

Increased Contrast

@media (prefers-contrast: more) {
  .button {
    border: 2px solid currentColor;
  }
}

This increases the button's border visibility when the user requests greater contrast.

Support varies among individual preference features. Provide usable default styles even when a particular preference query is unavailable.

The print media type allows stylesheets to adapt a document for printing without changing its normal screen appearance.

@media print {
  body {
    background-color: #fff;
    color: #000;
    font-size: 12pt;
  }
  nav,
  .print-button {
    display: none;
  }
  a {
    color: #000;
    text-decoration: underline;
  }
}

This example uses black text on a white background, hides navigation and print controls, and underlines links in printed output.

Print media queries can be combined with the @page at-rule when page dimensions and margins also need to be controlled.

Nested Media Queries

The @media at-rule can be nested inside another media query or a compatible conditional group rule.

@media screen {
  .card {
    padding: 20px;
  }
  @media (max-width: 600px) {
    .card {
      padding: 10px;
    }
  }
}

The inner styles apply only when both conditions match. In this example, the output must be a screen and the viewport must be 600 pixels wide or narrower.

Media queries can also be nested inside @supports to combine device conditions with CSS feature support checks.

@supports (display: grid) {
  @media (min-width: 768px) {
    .layout {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
    }
  }
}

The grid layout is applied only when the browser supports CSS Grid and the viewport meets the width condition.

@media Example

The following example changes a card layout from two columns to one column when the available viewport width is 600 pixels or narrower.

HTML

<div class="card-layout">
  <div class="demo-card">HTML</div>
  <div class="demo-card">CSS</div>
</div>

CSS

.card-layout {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.demo-card {
  padding: 20px;
  background-color: #0056b3;
  color: #fff;
  text-align: center;
}
@media (max-width: 600px) {
  .card-layout {
    grid-template-columns: 1fr;
  }
  .demo-card {
    background-color: #198754;
  }
}

Play in Editor

In the 300-pixel preview, the cards appear in one column with green backgrounds. Open the full editor and resize the browser window to see the cards switch between one and two columns.

Browser Support

The @media at-rule is Baseline Widely available and supported across all major modern browsers. Support for individual media features and newer range syntax may vary. See Can I Use? for compatibility information.

Specifications

The @media at-rule is defined by CSS Conditional Rules and the Media Queries specifications. These specifications describe conditional CSS rules, media types, media features, logical operators, and range comparisons.

CSS Conditional Rules Module Level 3

Media Queries Level 5