Codeskill

Learn to code, step by step

Responsive Design with SCSS: Fluidity and Elegance

Responsive design with SCSS matters once your pages get past the basics. Using variables, mixins, and functions to build layouts that adapt to different screen sizes.

Responsive design in practice

Responsive design means layouts that adapt to the screen they are on, rather than fixed widths that break on smaller devices. SCSS helps by letting you define breakpoints once and reuse them everywhere.

Variables and mixins for breakpoints

Store your breakpoints in a map. Write a mixin that wraps content in the right media query. Use that mixin throughout your stylesheet instead of repeating raw @media blocks.

Example: responsive mixin

$breakpoints: (
  'phone': 600px,
  'tablet': 900px,
  'desktop': 1200px
);

@mixin respond-to($breakpoint) {
  @media (min-width: map-get($breakpoints, $breakpoint)) {
    @content;
  }
}

.container {
  @include respond-to('tablet') {
    padding: 20px;
  }
}

Change a breakpoint value in one place and it updates across the project.

Grid layouts

A responsive grid is still a core layout pattern. SCSS loops make generating column classes straightforward.

Example: fluid grid system

@for $i from 1 through 12 {
  .col-#{$i} { width: 100% / 12 * $i; }
}

.container {
  display: flex;
  flex-wrap: wrap;
  .col-1, .col-2, .col-3, .col-4, .col-5, .col-6,
  .col-7, .col-8, .col-9, .col-10, .col-11, .col-12 {
    flex-basis: 100%;
  }
}

A 12-column grid where columns stack on smaller viewports.

Responsive typography

Text needs to scale too. Adjusting the root font size at different breakpoints makes all rem values scale with it.

Example

$base-font-size: 16px;

html {
  font-size: 100%;

  @include respond-to('tablet') {
    font-size: 112.5%; // Increases the font-size to 18px on tablets
  }

  @include respond-to('desktop') {
    font-size: 125%; // Increases the font-size to 20px on desktops
  }
}

Everything sized in rem grows proportionally as the root size changes.

Images and media

Images should never overflow their container. max-width: 100% and height: auto handle most cases.

Example

img {
  max-width: 100%;
  height: auto;
  display: block;
}

@include respond-to('tablet') {
  img {
    max-width: 80%;
  }
}

Function-based media queries

Functions can generate media query strings, which keeps breakpoint logic in one place.

Example

@function mq($width) {
  @return 'only screen and (min-width: #{$width})';
}

.container {
  @media #{mq(900px)} {
    width: 80%;
  }
}

Animations at different sizes

Animation timing can vary by screen size. Slower animations on small screens often feel better.

Example

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.fade-in-element {
  animation: fadeIn 1s ease-in-out;

  @include respond-to('phone') {
    animation-duration: 2s;
  }
}

SCSS with CSS frameworks

Building your own responsive system from scratch is fine for learning. In production, Bootstrap and Foundation ship with responsive mixins and variables you can customise with SCSS.

Define your breakpoints once, reuse them everywhere, and check the result on actual devices – not just by resizing your browser window.

PreviousAdvanced SCSS: Beyond the Basics