Susy: Creating a grid for given screen widths (breakpoint px values) and not knowing the width of a single column (a non-content-first approach)
Asked Answered
H

1

2

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:

  1. Window-px-widths-first approach (described above).

  2. $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.

  3. The last breakpoint is the containers' max-width. The site won't stretch further, it would have extra gutters instead.

  4. 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

  1. 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.

  2. Is my approach an elegant way of doing window-px-widths-first with Susy or it's an ugly piece of code?

  3. 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. :(

  4. What is the recommended way of going window-px-widths-first with Susy (and meeting the requirements i described above)?

  5. 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.

Homebody answered 19/11, 2012 at 20:6 Comment(1)
blog.cloudfour.com/…Ziagos
W
6

Not bad, but a few things you could clean up.

First the settings. There's no point in using Susy for a single column, so you could drop your small grid entirely, create it by hand (just padding), and have cleaner code. Once you add multiple columns, your current settings don't make much sense. 2 columns at 85%, with a 15% gutter? That adds up to 185% width. It works, because Susy is actually more interested in the ratio between the numbers, than the numbers themselves, but it's a bit ugly. I would change it to e.g. 85px and 15px or 8.5em and 1.5em. Since you are overriding the container anyway, that shouldn't change anything - just a bit more sensible.

The other main change I would make is to drop all the set-column-width calls, since your width is a 100% fluid override anyway. All it's doing is setting a width of 100% every time. Why bother? With that out of the way, I imagine you could automate the dev-background calls with a simple loop through your breakpoints.

$layouts: $layout-m $layout-l $layout-xl $layout-xxl
@each $layout in $layouts
  +at-breakpoint($layout)
    +dev-grid-bg

Creating a shortcut to change column-spans at different breakpoints would be difficult on your end or ours, and would add a fair amount of output bloat unless that is really the only change you are making at each size. What you have currently looks good.

Wobble answered 19/11, 2012 at 20:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.