Responsive design is a combinations of flexible grids, flexible embeds, and media queries:

  • design and build mobile first
  • design for touch inputs and don't count on hover
  • consider high resolution devices.

Mobile first

  • Design content and experiences mobile-first
  • build for mobile first and override for larger screen sizes
  • use progressive enhancement in tandem with a mobile-first approach.


Design with touch devices in mind and don't rely on hover states.

Touch targets should be at least 48x48 dp (device-independent pixels). This equates to a physical size of around 7-10mm (5mm at an absolute minimum). Keep an 8dp space between touchable elements where possible.

Use progressive enhancement to allow natural gestures on touch devices where appropriate. For example, sliding a carousel or scrolling a list. Don't rely solely on gestures and offer a simpler fallback like a click or tap. We recommend Hammer.js for implementing touch gestures.


To ensure proper rendering and touch zooming, add the viewport meta tag to your <head>:

<meta name="viewport" content="width=device-width, initial-scale=1"/>

Avoid using maximum-scale=1 or user-scalable=no as these restrict a user's ability to zoom.


The following table shows our breakpoints. These form the basis of everything responsive. They're used within:

BreakpointSASS variableWidth (px)Width (em)

Media queries

We use SASS MQ for composing media queries. Use $from with SASS MQ for min-width media queries to build mobile first. Override styles for wider screens widths:

.rule {
    background: blue;

    @include mq($from: sm) {
        background: red;
    @include mq($from: md) {
        background: green;
    @include mq($from: lg) {
        background: orange;

Note: our media queries are outputted in CSS as em based, converted from the pixel breakpoint values. This is so that layouts respond to the user's browser set font size.


Grids item widths are mobile first. Use breakpoint:columns for grid item widths across breakpoints:

<div class="grid">
    <div data-g="12 xs:6 md:4 lg:3">Item</div>
    <div data-g="12 xs:6 md:4 lg:3">Item</div>

Use mixins for responsive grids within custom components:

.layout {
    @include grid;

    &__sidebar {
        @include grid-item(12, $md: 3, $lg: 4);

    &__body {
        @include grid-item(12, $md: 9, $lg: 8);

[Read more about grids]({{ site.baseurl }}{% link foundations/ %}#grid-system)


Use responsive [spacing classes]({{ site.baseurl }}{% link foundations/ %}#css-classes) to override margins and paddings across screen sizes.


Use responsive [visibility classes]({{ site.baseurl }}{% link foundations/ %}#responsive-helpers) to show and hide elements across screen sizes.

Legacy browsers

Use Respond.js if you need to support min/max-width CSS3 media queries in IE8 and other older browsers.

    <!-- Put your CSS here, before Respond.js -->
    <!--[if lt IE 9]>
        <script src="//"></script>


Use our [maintain ratio component]({{ site.baseurl }}{% link components/ %}) to embed images or videos within responsive sites.

Responsive typography

Our typography uses relative units and we set a base font size on the html element. This means our typography is responsive and fluid by default.

Follow our [typography]({{ site.baseurl }}{% link foundations/ %}) rules and use our typography mixins.

Media queries in JavaScript

Use the breakpoints module:

import { breakpoints } from "@nice-digital/design-system";
// Or if you're building a core module: import breakpoints from "./breakpoints";

console.log(; // 900
console.log(breakpoints.matchesFrom("md")); // true/false

Support older browsers by polyfilling window.matchMedia:

Use matchMedia polyfill to support CSS3 capable browsers that do not implement the matchMedia API, e.g. IE9.

Use media-match polyfill for full support in older browsers from IE6+.