CSS Mobile First Design

Mobile-first design starts with the CSS needed for smaller viewports and then adds styles as more space becomes available. This approach creates a simple base layout that can be progressively enhanced for tablets, laptops, desktops, and other wider viewports.

Mobile-first CSS commonly uses min-width media queries. The styles outside the media queries form the base design, while additional rules are introduced at breakpoints where the content or layout needs more space.

What is Mobile First?

Mobile first is an approach to responsive design in which the initial CSS is written for the smallest layout requirements. Styles for wider layouts are then added as the available space increases.

This does not mean that a website is designed only for phones. The goal is to begin with a layout that works in limited space and then enhance that layout when wider viewports provide room for additional columns, spacing, or other presentation changes.

.content {
  width: 100%;
}

@media (min-width: 768px) {
  .content {
    width: 90%;
  }
}

The first rule applies at all viewport sizes. The rule inside the media query becomes applicable when the viewport is at least 768 pixels wide.

Start with Base Styles

In a mobile-first stylesheet, the default rules should create a usable layout without depending on a media query.

.cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 15px;
}

This creates a single-column card layout. A narrow viewport does not need an additional media query because the base layout already fits the available space.

Base styles can include typography, colors, spacing, flexible images, forms, navigation, and other presentation rules that should apply throughout the design.

Using min-width Media Queries

Mobile-first layouts commonly use min-width media queries to add or modify styles when the viewport reaches a particular width.

.cards {
  grid-template-columns: 1fr;
}

@media (min-width: 700px) {
  .cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

The cards use one column by default. At 700 pixels and wider, the layout changes to two columns.

Because the wider layout builds on the base rules, only the declarations that need to change have to be included inside the media query.

Enhancing the Layout

As more space becomes available, the design can progressively add layout features that are appropriate for wider viewports.

.page {
  display: block;
}

@media (min-width: 900px) {
  .page {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 30px;
  }
}

The narrow layout uses normal block flow. At 900 pixels and wider, the same content is arranged into a two-column Grid layout.

The HTML does not need to change simply because the viewport becomes wider. CSS controls how the existing content is presented.

Using Multiple Breakpoints

A responsive design can use more than one breakpoint when the layout benefits from additional changes.

.cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 15px;
}

@media (min-width: 600px) {
  .cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1000px) {
  .cards {
    grid-template-columns: repeat(3, 1fr);
  }
}

The layout begins with one column, changes to two columns at 600 pixels, and changes to three columns at 1000 pixels.

Each wider breakpoint builds on the rules that came before it. Normal cascade rules still apply, so later matching declarations can override earlier declarations when they have the same cascade priority.

Content-Based Breakpoints

Breakpoints should be added where the content or layout needs them rather than being based only on common device dimensions.

For example, a group of cards may work well in one column until the viewport becomes wide enough to display two cards without making either card too narrow. That width can become a useful breakpoint.

@media (min-width: 720px) {
  .cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

If 720 pixels is where the content has enough room for two useful columns, it can be chosen because of the layout rather than because it represents a particular device.

Mobile First vs Desktop First

Mobile-first and desktop-first stylesheets can both create responsive layouts. The main difference is the direction in which the layout changes are introduced.

Approach Base Styles Common Width Query
Mobile First Smaller layout min-width
Desktop First Wider layout max-width

A desktop-first layout might begin with several columns and remove columns as the viewport becomes narrower.

.cards {
  grid-template-columns: repeat(3, 1fr);
}

@media (max-width: 700px) {
  .cards {
    grid-template-columns: 1fr;
  }
}

A mobile-first version begins with the single-column layout and adds columns when enough space becomes available.

.cards {
  grid-template-columns: 1fr;
}

@media (min-width: 700px) {
  .cards {
    grid-template-columns: repeat(3, 1fr);
  }
}

Mobile-First Typography and Spacing

Mobile-first techniques can also be applied to typography and spacing. Smaller values can be used initially and adjusted when wider layouts benefit from additional space.

.page {
  padding: 1rem;
}
h1 {
  font-size: 2rem;
}

@media (min-width: 800px) {
  .page {
    padding: 2rem;
  }
  h1 {
    font-size: 3rem;
  }
}

This increases both page padding and heading size when more viewport space is available.

Not every value needs to change at a breakpoint. Relative units and functions such as clamp() can also create flexible sizing without adding extra media queries.

Mobile-First Navigation

Navigation can begin with an arrangement that fits narrow screens and change when additional horizontal space becomes available.

.navigation {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

@media (min-width: 700px) {
  .navigation {
    flex-direction: row;
  }
}

The links are stacked vertically by default and become a horizontal row at 700 pixels and wider.

More complex navigation systems may require additional HTML, CSS, or JavaScript for controls and accessibility, but the same mobile-first principle can be used for their responsive layout.

Mobile-First Best Practices

Keep the base layout usable and avoid adding breakpoints unless the content or design needs them. This keeps the responsive rules easier to understand and maintain.

Practice Purpose
Start with a simple base layout Provides a usable design for narrow viewports.
Use flexible sizing Allows content to adapt between breakpoints.
Add breakpoints when needed Lets the content determine where layout changes occur.
Change only necessary declarations Reduces duplicated CSS between breakpoints.
Test between breakpoints Helps identify overflow and awkward intermediate layouts.

Mobile-First Example

The following example begins with one card per row and progressively adds columns as the viewport becomes wider.

.cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 15px;
}

@media (min-width: 550px) {
  .cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 850px) {
  .cards {
    grid-template-columns: repeat(3, 1fr);
  }
}

Open the example in the editor and change either breakpoint. Drag the divider between the code and result panes to change the preview width and see how the layout progresses from one column to two columns and then three columns.

Play in Editor