Building Mobile‑First Layouts with Materialize CSS’s 12‑Column Grid
Learn how Materialize CSS’s 12‑column responsive grid lets you build mobile‑first layouts with simple class names, see a worked product‑card example, and understand the limits of its fixed breakpoints.
29 Nov 2025, 20:58 UTC

Why a grid matters
When you start a new page you often need a layout that works on phones, tablets and desktops without writing a handful of media queries. Doing that by hand leads to duplicated breakpoints and makes future changes error‑prone. Materialize CSS ships a ready‑made 12‑column fluid grid that lets you declare how many columns an element should span at each breakpoint using simple class names.
Core concepts
Container and row
The grid expects a .container (fixed width) or .container-fluid (full width) wrapper. Inside it you place a .row; the row applies negative margins that counteract the container’s padding, allowing columns to sit flush with the edges.
Column classes
Each column is a div with one or more of the following breakpoint prefixes:
s– small screens (<600px)m– medium screens (≥600px and <992px)l– large screens (≥992px)
The number after the prefix tells how many of the 12 columns the element should occupy. For example s12 m6 l4 means: full width on small, half width on medium, one‑third width on large.
Offset, push and pull
When you need to shift a column without changing its size, Materialize offers .offset-*, .push-* and .pull-* helpers that work with the same breakpoint prefixes. They are useful for creating asymmetrical layouts or fixing source‑order issues.
Worked example: product card list
Below is a minimal HTML file that shows three product cards reflowing from a stacked layout (one per row) on phones, to two‑column on tablets, to three‑column on desktops.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Product list with Materialize grid</title>
<!-- Materialize CSS via CDN -->
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
</head>
<body>
<div class="container">
<h4 class="center-align">Product catalog</h4>
<div class="row">
<!-- Card 1 -->
<div class="col s12 m6 l4">
<div class="card">
<div class="card-content">
<span class="card-title">Widget A</span>
<p>Compact description.</p>
</div>
</div>
</div>
<!-- Card 2 -->
<div class="col s12 m6 l4">
<div class="card">
<div class="card-content">
<span class="card-title">Widget B</span>
<p>Compact description.</p>
</div>
</div>
</div>
<!-- Card 3 -->
<div class="col s12 m6 l4">
<div class="card">
<div class="card-content">
<span class="card-title">Widget C</span>
<p>Compact description.</p>
</div>
</div>
</div>
</div>
</div>
<!-- Materialize JS (optional for other components) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</body>
</html>
Save the snippet as grid-demo.html and open it in a browser. Use the developer tools’ responsive design mode or simply resize the window:
- <600px → each card takes the full width (
s12). - 600px‑991px → two cards per row (
m6). - ≥992px → three cards per row (
l4).
No JavaScript is required for the grid itself; the materialize.min.js tag is only needed if you later add components like modals or dropdowns.
Trade‑offs and limitations
The grid’s breakpoints are fixed at 600 px, 992 px and 1200 px (the latter is the point where the container switches to its max width). If your design needs a different cutoff—for example 768 px for a tablet‑specific layout—you must either:
- Override the default CSS with your own media queries, or
- Recompile Materialize from its Sass source, changing the
$grid-breakpointsmap.
Both approaches add a maintenance step, but they keep the grid’s simplicity for the majority of projects that fit the default breakpoints.
Actionable next steps
- Add the CDN links for Materialize CSS (and JS if you need other components) to your project’s
<head>. - Wrap your page content in
<div class="container">and use<div class="row">as a wrapper for each horizontal group. - Apply column classes like
s12 m6 l4to the elements you want to size. - Test the layout by resizing the browser window or using device‑emulation in DevTools.
- If you need different breakpoints, fork the Sass variables, rebuild the CSS, and replace the CDN link with your custom build.
With these steps you can create clean, mobile‑first layouts quickly, while keeping the HTML easy to read and the CSS free of custom media queries—unless your design truly demands them.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.