I'm using Susy.
I failed leveraging the content-first approach and decided to go window-px-widths-first
At first i tried the content-first approach to grids, but soon i found my site behaving unexpectedly on different devices. It would display a mobile layout where i wanted a tablet layout, etc. I ended up adjusting em values of Susy settings for them to match certain screen widths (px values). The code got ugly and i realized that i wasn't actually using the content-first approach any more.
Here's a static snapshot of the homepage of a site that i created using this faulty approach and a snapshot of its code.
So i decided to dump the content-first approach completely and use px values in the first place.
Before writing code i formulated requirements for my grid
First of all i grouped different devices by their screen size. Then i came up with px values for breakpoints that are the most appropriate for those device groups:
Break- Layout Number of Common
points name columns usage
(px) (sample)
0 ┬
│
│ S 1 Smartphones-portrait, old phones
│
400 ┼
│ M 2 Smartphones-landscape
600 ┼
│ L 3 Tablets-portrait
800 ┼
│ XL 4 Tablets-landscape, netbooks
1000 ┼
│ XXL 5 Laptops, desktop computers
1200 ┼
↓
I suppose the following assumptions/requirements:
Window-px-widths-first approach (described above).
$container-style is fluid. When screen width is somewhere in between two breakpoints, containers' widths are automatically adjust to match the larger breakpoint. The number of columns in the layout is not changed and corresponds to the lower breakpoint.
The last breakpoint is the containers' max-width. The site won't stretch further, it would have extra gutters instead.
Mobile-first. Start with the "S" layout and override it with other layouts as the screen goes wider.
After a lot of thought my approach evolved to the following code
(This code is a synthetic example. I took excerpts from my actual code and made some adaptations, so it may miss something or have inconsistencies.)
<div id="header-wrapper">
<header id="header">
...
</header>
</div>
<div id="main-wrapper">
<div id="main">
<article id="content">...</article>
<aside id="sidebar">...</aside>
</div>
</div>
<div id="footer-wrapper">
<footer id="footer">
...
</footer>
</div>
/////////////
// Variables
/////////////
$development: true // This enables susy-grid-backgrounds and outlines
// Breakpoints
$bp-s-m: 400px
$bp-m-l: 600px
$bp-l-xl: 800px
$bp-xl-xxl: 1000px
$max-width: 1200px
// Columns
$cols-s: 1
$cols-m: 2
$cols-l: 3
$cols-xl: 4
$cols-xxl: 5
// Layouts
// $layout-s is not necessary due to a mobile-first approach
$layout-m: $bp-s-m $cols-m
$layout-l: $bp-m-l $cols-l
$layout-xl: $bp-l-xl $cols-xl
$layout-xxl: $bp-xl-xxl $cols-xxl
// Default grid settings
$total-columns: $cols-s
$column-width: 85%
$gutter-width: 100% - $column-width
$grid-padding: 1em
$container-width: 100%
$container-style: fluid
+border-box-sizing
/////////////
// Mixins
/////////////
// A couple of mixins to open the developer's third eye
=dev-outline
@if $development
outline: 1px solid red
=dev-grid-bg
+dev-outline
@if $development
+susy-grid-background
// A custom container declaration
=standard-container
+container // ← An actual line of Susy code, yay! :D
// This whole post is actualy an attempt to make use of it.
max-width: $max-width
+dev-grid-bg
+at-breakpoint($layout-m)
+set-container-width
+dev-grid-bg
+at-breakpoint($layout-l)
+set-container-width
+dev-grid-bg
+at-breakpoint($layout-xl)
+set-container-width
+dev-grid-bg
+at-breakpoint($layout-xxl)
+set-container-width
+dev-grid-bg
/////////////
// Backgrounds
/////////////
// The wrapper divs are necessary for screen-wide backgrounds
html
background: url('../images/main-background.png') // also repeat, color, this kind of stuff
#header-wrapper
background: url('../images/header-background.png')
#footer-wrapper
background: url('../images/footer-background.png')
/////////////
// Containers
/////////////
// Actually declared in separate SASS files
#header, #main, #footer
+my-container
/////////////
// Columns
/////////////
// An example of declaring columns
$cols-sidebar: 1
#sidebar-first
+dev-outline
+at-breakpoint($layout-l)
+span-columns($cols-sidebar, $cols-l)
+at-breakpoint($layout-xl)
+span-columns($cols-sidebar, $cols-xl)
+at-breakpoint($layout-xxl)
+span-columns($cols-sidebar, $cols-xxl)
#content
+dev-outline
+at-breakpoint($layout-l)
+span-columns($cols-l - $cols-sidebar omega, $cols-l)
+at-breakpoint($layout-xl)
+span-columns($cols-xl - $cols-sidebar omega, $cols-xl)
+at-breakpoint($layout-xxl)
+span-columns($cols-xxl - $cols-sidebar omega, $cols-xxl)
Here is a static snapshot of the homepage of a site that i created using this approach and snapshot of its code.
Questions
Following the window-px-widths-first approach is my deliberate decision and is a given to the following questions. I appreciate your arguments for content-first, but please do not confine yourself to stating that i'm wrong, please answer the following questions specific to window-px-widths-first.
Is my approach an elegant way of doing window-px-widths-first with Susy or it's an ugly piece of code?
How can i make my code more graceful?
I don't like those numerous at-breakpoint declarations that i have to repeat for every container and every column. I could only think of using a poorly documented possibility of specifying multiple layouts for
+container
. But as long as+set-container-width
is not the only code i do within every media query, even that idea is not an option. :(What is the recommended way of going window-px-widths-first with Susy (and meeting the requirements i described above)?
Please reveal any shortcomings of my code you find. I'm novice in SASS and i'm sure you can suggest more efficient ways of doing the same stuff.