The big appeal behind CSS frameworks (like Bootstrap and Foundation) is that they come with a responsive grid system all set and ready to go. The downside is that you have to be content with their column count, the width of their gutters, and all their classes in your markup. What if your project requirements go beyond the defaults of a prefab CSS grid framework? This article will show how you can build and maintain your own unique responsive grids with two Sass libraries: Susy and Breakpoint.
Susy Basics
For a more detailed introduction to using Susy to manage your grids, check out this SitePoint article or this slidedeck. We’ll just hit the high points here so that you have some context for what follows.
All your grid config settings live in a map called $susy
. You can use the key-value pairs in this map to set your max-width (container
), column count (columns
), and gutter width (gutters
).
With Susy, you specify a container element for your grid elements by using the container()
mixin. The selector that includes that mixin will then be assigned the max-width from the container
value in $susy
, centered with left and right margins set to auto
, and given a clearfix.
Each column inside that container is controlled with the span()
mixin. This mixin typically takes three arguments: span (number of parent columns it will fill), layout (number of parent columns if different from default), and location (first/alpha, last/omega, or a column number).
$susy: (
container: 70em,
columns: 12,
gutters: 1/6
);
.main {
@include container;
}
.content {
@include span(8 of 12 first);
}
.sidebar {
@include span(4 of 12 last);
}
If you want to look under the hood of a more detailed Susy grid, here’s a Sassmeister gist for you to play with.
Breakpoint Basics
If you want a detailed look at how to use Breakpoint, a Sass plugin for managing media queries, this SitePoint article should answer most of your questions. Again, we’ll cover some basics for the sake of introduction.
Breakpoint provides a single powerful mixin for handling almost any kind of media query: breakpoint()
. If you pass the mixin a single measurement (like 960px), it will use that number as a min-width media query. If you provide two measurements, it will use them as min-width and max-width values. If you pass a keyword / value pair, you can create any media query you need: height, orientation, resolution, etc. You can also pass several keyword / value pairs to create complex queries: just enclose each pair in parentheses:
.element {
font-size: 1.3em;
@include breakpoint((min-width 30em) (max-width 60em) (orientation portrait)) {
font-size: 1.5em;
}
}
Mixin: susy-breakpoint()
Now that we’ve got the basics of Susy & Breakpoint, let’s look at how they work together to help us quickly build responsive grid layouts. If you have both imported into your project, you can use the susy-breakpoint()
mixin to combine their functions.
The susy-breakpoint()
mixin wraps Breakpoint’s media queries around Susy’s grid output. It requires two parameters (and takes an optional third parameter).
The first parameter you’d pass to susy-breakpoint()
is the media query data you plan to pass to Breakpoint. This data is passed straight to the Breakpoint mixin and used to generate the media query for this part of your code.
The second parameter is the Susy grid layout: at its simplest, it can be a number: a column count. You can also pass it a map that contains the same keys as $susy
. This column count sets the “context” for everything that Susy calculates inside this mixin. For example, if you pass “16” as the layout, all the Susy grid mixins and functions inside susy-breakpoint()
will use 16 as the column count value, regardless of what columns
value is in the $susy
config map.
If you’re familiar with the concept of scoped variables, this is simply a way to scope a new column count to the current media query. In fact, if you pass a map that follows the $susy
pattern, any values in that map will be scoped to the generated media query context.
The third (optional) parameter for susy-breakpoint()
is Breakpoint’s no-query value. This parameter allows you to handle fallbacks for browsers that don’t support media queries. If you enable $breakpoint-no-query-fallbacks
and pass a class as this third parameter, it will be used as a wrapper class around the current selector (instead of a media query).
$breakpoint-no-query-fallbacks: true;
.element {
color: blue;
@include susy-breakpoint(480px, $susy, '.no-mq') {
color: red;
}
}
// output
.element {
color: blue;
}
@media screen and (min-width: 480px) {
.element {
color: red;
}
}
.no-mq .element {
color: red;
}
Note: the example above doesn’t use Susy grid mixins inside the query: it’s just demonstrating how to use Breakpoint’s no-query.
One Container Grid with Changing Column Elements
There are two ways to manage responsive grids. You’re probably most familiar with the first one: all column measurements are based on the same column count and elements change span count at various breakpoints. This is the way nearly every CSS grid framework operates. Let’s look at how we can create that with Susy and Breakpoint.
The first thing we need is our $susy
map and a couple of breakpoint variables. We’ll also turn on Breakpoint’s no-query feature.
$susy: (
container: 64em,
columns: 12,
gutters: 1/6
);
$bp-medium: 32em;
$bp-large: 60em;
$breakpoint-no-query-fallbacks: true;
After our map is set up, we’ll declare our container element:
.container {
@include container;
}
Inside that container, we’ll set up our two child elements as full-width spans. This will be our default for small screens: the “columns” are stacked vertically.
.content {
@include span(12 last);
}
.sidebar {
@include span(12 last);
}
Let’s move up to the medium and large breakpoints. We’ll do that with the susy-breakpoint()
mixin. We’re passing $susy
as the layout parameter. We could also use 12
(the columns
value in $susy
). I know, this may feel a bit redundant now, but later we’ll see how useful passing a new map as the layout can be.
.content {
@include span(12 last);
@include susy-breakpoint($bp-medium, $susy) {
@include span(6 first);
}
@include susy-breakpoint($bp-large, $susy) {
@include span(8 first);
}
}
.sidebar {
@include span(12 last);
@include susy-breakpoint($bp-medium, $susy) {
@include span(6 last);
}
@include susy-breakpoint($bp-large, $susy) {
@include span(4 last);
}
}
Now we’ve got a basic responsive grid. On any screen smaller than 32em, the content and the sidebar will be full-width and stacked vertically. At 32em, those elements will appear side-by-side at half the total width. At 60em, the ratio between their widths shifts from 1/1 to 2/1. At 64em, the container will stop expanding and will be centered inside the viewport.
Changing Container Grid with Stable Column Spans
The other (and admittedly, more complicated) way to set up responsive grids is to set fixed span values for the columns and change the container column properties. To do this, you’ll need to change the column ratios at each breakpoint by using a column list in the columns
value of a $susy
-style maps for each breakpoint:
$susy: (
container: 70em,
columns: 1,
gutters: 1/16
);
$medium: (
columns: 1 1
);
$large: (
columns: 2 1
);
$bp-medium: 32em;
$bp-large: 60em;
Putting a list of numbers in the columns
value tells Susy to create columns widths that match the proportions of those numbers. The span()
mixin will size then elements to match those proportions based on their location. So columns: 1 1
creates two equal width columns (just like columns: 2
would do), while columns: 2 1
creates two columns and makes the first twice as wide as the second.
To use these ratios, we’d call susy-breakpoint()
and span()
in the following way:
.container {
@include container;
}
.primary {
@include span(1 at 1);
@include susy-breakpoint($bp-medium, $medium) {
@include span(1 at 1);
}
@include susy-breakpoint($bp-large, $large) {
@include span(1 at 1);
}
}
.secondary {
@include span(1 at 1);
@include susy-breakpoint($bp-medium, $medium) {
@include span(1 at 2);
}
@include susy-breakpoint($bp-large, $large) {
@include span(1 at 2);
}
}
The at
location provides the magic here: in the large breakpoint, the first column is wider than the second, so specifying the location tells Susy to make .primary
the width of the first number in the columns
list. Specifying that the .secondary
element is at location 2
tells Susy that it should match the ratio of the second number in the columns
list (and that it’s the last element and should have its margin-right
removed). We have to repeat the span()
mixin inside each susy-breakpoint()
because Susy needs the new columns
measurements to recalculate the width percentages at each breakpoint. Try this out in real life with these Sassmeister gists: one, two.
Conclusion
Susy and Breakpoint make a pretty powerful team here. Not only can you create grids that are precisely as simple or as complex as you need them to be, you can also change those grids as much as your project requires at any breakpoint. Please ask any follow-up questions you have in the comments, or leave a comment to share a clever grid you’ve created with Susy and Breakpoint!
Frequently Asked Questions about Creating a Responsive Grid System with Susy and Breakpoint
How does Susy and Breakpoint differ from other responsive grid systems?
Susy and Breakpoint are unique in their approach to creating responsive grid systems. Unlike other systems that use predefined classes and structures, Susy and Breakpoint allow for a more flexible and customizable approach. They are Sass-based tools that let you design your own semantic grid system based on the needs of your project. This means you have full control over the grid structure, column widths, breakpoints, and more. This level of customization is not typically available in other grid systems.
Can I use Susy and Breakpoint with other CSS frameworks?
Yes, you can use Susy and Breakpoint with other CSS frameworks. They are designed to be flexible and adaptable, allowing you to integrate them into your existing CSS framework. This means you can leverage the power of Susy and Breakpoint’s customizable grid system while still using the components and features of your preferred CSS framework.
How do I set up Susy and Breakpoint in my project?
Setting up Susy and Breakpoint in your project involves a few steps. First, you need to install Node.js and npm on your machine. Then, you can install Susy and Breakpoint using npm. Once installed, you can import them into your Sass files and start using them to create your grid system. Detailed instructions on how to set up Susy and Breakpoint can be found in the article.
How do I define breakpoints in Susy and Breakpoint?
Breakpoints in Susy and Breakpoint are defined using the breakpoint
mixin. You can specify the width at which the breakpoint should occur, and then define the styles that should apply at that breakpoint. This allows you to create responsive designs that adapt to different screen sizes.
What are the advantages of using a responsive grid system?
A responsive grid system allows your website to adapt to different screen sizes, ensuring a consistent and user-friendly experience across all devices. It allows for a flexible layout that can accommodate a wide range of screen sizes, from small mobile devices to large desktop monitors. This is particularly important in today’s multi-device world, where users expect websites to function seamlessly on any device they use.
How can I customize the column widths in Susy?
In Susy, you can customize the column widths by defining your own grid settings. You can specify the number of columns, the gutter width, and the column width. This allows you to create a grid system that perfectly fits your design needs.
Can I use Susy and Breakpoint for complex grid layouts?
Yes, Susy and Breakpoint are designed to handle complex grid layouts. They provide a flexible and powerful grid system that can be customized to fit any design. Whether you’re creating a simple two-column layout or a complex multi-column design, Susy and Breakpoint can handle it.
How do I handle nested grids in Susy?
Susy provides a span
mixin that you can use to handle nested grids. This mixin allows you to specify how many columns a nested element should span, allowing you to create complex nested grid layouts.
What is the learning curve for Susy and Breakpoint?
As with any new tool, there is a learning curve when starting with Susy and Breakpoint. However, their flexibility and power make them worth the effort. If you’re familiar with Sass and CSS, you should be able to pick up Susy and Breakpoint fairly quickly.
Are there any resources for learning more about Susy and Breakpoint?
Yes, there are many resources available for learning more about Susy and Breakpoint. The official documentation for both tools is a great place to start. There are also many tutorials and articles available online that can help you get started with these tools.
James is a Senior Front-End Developer with almost 10 years total experience in freelance, contract, and agency work. He has spoken at conferences, including local WordPress meet-ups and the online WP Summit. James's favorite parts of web development include creating meaningful animations, presenting unique responsive design solutions, and pushing Sass’s limits to write powerful modular CSS. You can find out more about James at jamessteinbach.com.