May, 2009 | Todd Ross Nienkerk
Drupal theming using the
960.gs grid system
Originally presented at DrupalCamps Copenhagen, Helsinki, and Stockholm 2009
Photo: Kristin Hillery
Todd Ross Nienkerk
‣ Co-founder of Four Kitchens, a Drupal
design and development firm in Austin, Texas
‣ One of the implementers of the new
Drupal.org redesign
‣ Member of the Drupal documentation
Source: Grids are Good by Khoi Vinh and Mark Boulton
History of the grid
‣ The practice of using a grid to guide design and
page layout is nearly a century old
‣ In the 1910s and 1920s, ornamental design gave
way to Rationalism and New Objectivity
‣ This shift in design was part of a much larger
movement towards function over form
Source: Grid (page layout) on Wikipedia
‣ After World War II, a number of graphic designers,
influenced by the modernist ideas of Die neue
Typographie (The New Typography), questioned
the relevance of the conventional page layout of the time
‣ They devised a flexible system to help designers
achieve coherency in organizing the page
Source: Grid (page layout) on Wikipedia
‣ The result was the modern typographic grid
associated with the International Typographic Style
‣ Grid Systems in Graphic Design, the seminal work
on the subject, helped propagate the use of the grid in Europe and, later, in North America
Source: Grids are Good by Khoi Vinh and Mark Boulton
Nearly a century ago
‣ Modernists looked to build a new aesthetic by...
‣ deriving beauty from the innate qualities of the
machine
‣ championing standardization
Source: Grids are Good by Khoi Vinh and Mark Boulton
Today
‣ Web designers have turned to grid-based design
in order to...
‣ derive beauty from the innate qualities of the
browser
‣ champion standardization
‣ 16 years after the invention of the web, we are
1 Source: Software framework on Wikipedia
Grid systems on the web
‣ On the web, grid systems usually take the form of
CSS frameworks
‣ A framework is a “reuseable abstraction of code
wrapped in a well-defined API”1
‣ A collection of tools and shortcuts designed to
Examples of frameworks
‣ Ruby on Rails is a well-known Ruby framework
‣ jQuery is a JavaScript framework
‣ Drupal itself can be considered a web application
framework
‣ Includes many APIs for working with databases,
CSS frameworks
‣ Apply the principles of software frameworks to
web design
‣ They provide standardized rules and shortcuts for:
‣ browser resets ‣ typography
‣ navigation ‣ print style ‣ and...
Layout
‣ When applied to web design, grid systems are CSS
frameworks that provides standardized rules and shortcuts for building a website’s layout
1) Saves time
2) Saves money
Stop reinventing the
wheel
‣ Reduces the amount of CSS and markup you need
to duplicate each time you start a project
‣ No need to refer to old projects to figure out how
Stop fixing and start
designing
‣ Shortens testing phases by providing built-in
support for noncompliant browsers
‣ Minimize Internet Explorer hacks in your layout
‣ A well-tested grid system will rarely be the source
Stop deconstructing CSS
‣ Understanding someone else’s design is much
How do grid systems
work?
Example based on 960.gs (12-column)
Columns
‣ Grid systems are built
using columns
‣ Columns are a grid
system’s smallest unit of measurement
‣ Most grid systems
Example based on 960.gs (12-column)
Column width
‣ Page regions (header,
content, sidebars, etc.) are defined by column width
‣ As in: “The header is
Example based on 960.gs (12-column)
Gutters (margins)
‣ Margins or padding are
used to create gutters between columns
‣ These gutters provide
margins between page regions
Lean and versatile CSS
‣ A grid system’s CSS should:
‣ Be lean and efficient
‣ Be versatile and reusable
‣ Ensure consistent behavior across all common
Wrapping
<div>
elements
‣ In fixed-width grid systems, the entire layout is
wrapped inside a single <div> element
‣ <div> elements wrap the page regions and define
their widths according to the number of columns they span
‣ These <div> elements may be nested to create
Example based on 960.gs (12-column)
Floating
<div>
elements
‣ The wrapping <div>
elements are assigned a column width using a CSS class
‣ Because these classes
also float the elements, they simply fall into
place on the page
class: grid-12 class: grid-8 class: grid-4 class: grid-4 class: grid-4
What can grid systems
look like?
Example based on 960.gs (12-column)
Example based on 960.gs (12-column)
Example based on 960.gs (12-column)
Example based on 960.gs (12-column)
Painting by Piet Mondriaan (later Mondrian)
Source: 960.gs
What is 960.gs?
‣ 960.gs — also known as the 960 Grid System —
was created by Nathan Smith in order to “streamline web development workflow”
‣ It’s both a prototyping and development
framework
‣ “The premise of the system is ideally suited to
rapid prototyping, but it would work equally well when integrated into a production environment.”
Source: 960.gs
‣ Download it for free at http://960.gs
‣ GPL and MIT licensed
‣ The 960.gs download includes:
‣ Printable sketch sheets for doodling
‣ Design templates for all most applications:
Photoshop, Illustrator, Inkscape, OmniGraffle, etc.
Source: 960.gs
Technical specs
‣ 960px wide with a 940px usable area
‣ Two versions: 12- and 16-column
‣ These can be implemented separately or
simultaneously
‣ Each column has a 10px margin on the left and
right, which creates a 20px gutter between columns
Source: 960.gs
12-column version
Columns are 60px wide Gutters are 20px wide
10px margin on the left and right prevents collision with browser chrome
Available
working area is 940px wide
Source: 960.gs
16-column version
Columns are 40px wide
Using both versions
simultaneously
‣ You can use 12-column classes inside a 16-column
grid — and vice versa
‣ This is possible because 12 and 16 are both
multiples of 2 and 4
‣ 2 * 6 = 12
‣ 2 * 8 = 16
‣ 4 * 3 = 12
‣ In other words, when you divide the layout into
halves and quarters, you can use 12- and 16-column version simultaneously
‣ Watch what happens when you lay one grid on top
of the other:
Halves
‣ This flexibility allows designers to work with both
60px- and 40px-wide columns
‣ If 12 or 16 columns don’t suit you, 960 is also
divisible by 2, 3, 4, 5, 6, 8, 10, 15, 20, 24, 30, 32, 40, 48, 60, 64, 80, 96, 120, 160, 192, 240, 320 and 480
CSS and markup
Note: 960.gs uses underscores in its CSS class names. To avoid confusion, the examples that follow will use hyphens instead, as this is The Drupal Way.
Containers
‣ Grids must be wrapped
in a container <div>
‣ Containers center the
content and define which version of the grid will be implemented .container-12, .container-16 { margin-left: auto; margin-right: auto; width: 960px; }
Grids
‣ Grids are held inside
containers and are
floated left so they fall into place
automatically
‣ They also provide 10px
margins on the left and right .grid-1, .grid-2, .grid-3, ... .grid-16 { display: inline; float: left; position: relative; margin-left: 10px; margin-right: 10px; }
Grid widths
‣ The width of each grid
is determined by the container that wraps it
‣ For example, a
one-column grid is either 60px or 40px depending on whether it’s a 12- or 16-column layout .container-12 .grid-1 { width: 60px; } .container-16 .grid-1 { width: 40px; }
‣ Note that grid width does not increase by 60px or
40px each time
‣ Each increase must account for the 20px gutter
between grids .container-12 .grid-1 { width: 60px; } .container-12 .grid-2 { width: 140px; } .container-12 .grid-3 { width: 300px; } .container-16 .grid-1 { width: 40px; } .container-16 .grid-2 { width: 100px; } .container-16 .grid-3 { width: 160px; }
Putting containers and
grids together
.grid-3 .grid-6 .grid-3
Prefixes and suffixes
‣ If you want to leave
space between
columns, use a prefix or suffix class
‣ Prefix classes add
padding to the left of a column
‣ Suffix classes add
padding to the right
.container-12 .prefix-1 { padding-left: 80px; } .container-12 .suffix-1 { padding-right: 80px; }
Adding a prefix and suffix
.grid-3 .grid-4 .prefix-1 .suffix-1 .grid-3 .container-12Multiple rows
.grid-3 .grid-4 .prefix-1 .suffix-1 .grid-3 .container-12 .grid-12Multiple rows: markup
<div class="container-12"> <!-- row 1 -->
<div class="grid-12">
This grid occupies the full width </div>
<!-- row 2 -->
<div class="grid-3"> One wide
</div>
<div class="grid-4 prefix-1 suffix-1">
Four wide with a prefix and suffix of one each </div> <div class="grid-3"> One wide </div> </div> <!-- /container --> No need to put each row in its own wrapping <div> The container <div>
defines the layout version in use
Stack content vertically
with nested grids
.grid-3 .grid-6 .grid-3 .container-12 .grid-6 .grid-6
‣ Here’s the catch: Because each grid includes a
10px left and right margin, nesting grids can break your layout .grid-3 .grid-6 .grid-3 .container-12 .grid-6 .grid-6
Alpha and omega fix
broken nesting
‣ When nesting grids, use the alpha and omega
classes to remove the margins
‣ alpha removes the left margin. It’s the first nested
grid.
‣ omega removes the right margin. It’s the last
.grid-3 .grid-3 .alpha .grid-3 .container-12 .grid-6 .alpha .omega .grid-3 .omega .grid-6 .alpha removed the left margin
.omega removed the right margin
Additional resources
‣ 960 Gridder and bookmarklet
‣ Variable grid system generator
‣ Other grid systems based on 960.gs
‣ Fluid 960.gs
‣ Typogridphy: Typographical and grid layout CSS
framework
The NineSixty theme
Drupal’s implementation of 960.gs is even better than the original
Source: Drupal.org
About NineSixty
‣ NineSixty is the Drupal port of 960.gs
‣ Developed by Joon Park, aka dvessel on
Drupal.org
‣ Intended to be used as a base theme
‣ Currently a candidate for Drupal 7 core
NineSixty’s improvements
‣ Content-first layout using “push” and “pull” classes
‣ Dynamic grid widths based on context
‣ Debugging tools and grid visualization
Content-first layout
‣ A design convention in which the content is output
as close to the top of the markup as possible
‣ Content should be output before all sidebars
‣ Some designers believe it should be output
before a site’s main navigation
‣ This can be very difficult to achieve on a site with
Push and pull classes
‣ Content-first layout can be achieved in NineSixty
by “pushing” the content grid to the right while “pulling” a sidebar to the left
‣ These classes use the same naming convention
as .grid-X, .prefix-X, and .suffix-X, where X is the grid’s width:
Source: NineSixty’s README.txt
‣ Push and pull values should match the grid value
of the opposite grid
<div class="container-12">
<div id="content" class="grid-6 push-3"> Content
</div>
<div id="sidebar-left" class="grid-3 pull-6"> Sidebar: Left
</div>
<div id="sidebar-right" class="grid-3"> Sidebar: Right
</div> </div>
Match numbers to swap locations
.container-12
.grid-3
.grid-6 .grid-3
<div class="container-12">
<div id="content" class="grid-6"> Content
</div>
<div id="sidebar-left" class="grid-3"> Sidebar: Left
</div>
<div id="sidebar-right" class="grid-3"> Sidebar: Right
</div> </div>
<div class="container-12">
<div id="content" class="grid-6 push-3"> Content
</div>
<div id="sidebar-left" class="grid-3 pull-6"> Sidebar: Left
</div>
<div id="sidebar-right" class="grid-3"> Sidebar: Right
</div> </div>
After adding push and pull
.container-12 .grid-3 .pull-6
.grid-6
Dynamic grid widths
‣ In some cases, you may want grids to resize
themselves when a region isn’t populated
‣ For example, a 3-6-3 layout should become 3-9 if
the right column is empty
‣ Dynamic width assignment is handled using the
ns() function
‣ X, Y, and Z are all width values
‣ class can be grid, prefix, suffix, push, or pull ‣ $region can be any theme region
‣ Use as many pairs as you like
Structure of
ns()
ns('class-X', $region, Y, $region, Z, ...)
Default value
These “pairs” subtract from the
Source: NineSixty’s page.tpl.php
Implementing
ns()
<div id="main" class="column <?php print ns('grid-16', $left, 4, $right, 3) . ' ' . ns('push-4', !$left, 4); ?>">
<?php print $content; ?> </div>
<?php if ($left): ?>
<div id="sidebar-left" class="column sidebar region grid-4 <? php print ns('pull-12', $right, 3); ?>">
<?php print $left; ?> </div>
<?php endif; ?>
<?php if ($right): ?>
<div id="sidebar-right" class="column sidebar region grid-3"> <?php print $right; ?>
</div>
<?php endif; ?>
Source: NineSixty’s page.tpl.php
<?php print ns('grid-16', $left, 4, $right, 3) . ' ' . ns('push-4', !$left, 4); ?>
From #main:
ns('grid-16', $left, 4, $right, 3)
ns('push-4', !$left, 4)
Default width
If left sidebar is present, subtract 4 from default width.
If right sidebar is present, subtract 3 from default width.
If left sidebar is not present, subtract 4 from the push value. This will result
in no push, as 4-4 = 0 Default
Source: NineSixty’s page.tpl.php
<?php php print ns('pull-12', $right, 3); ?>
From #sidebar-left: ns('pull-12', $right, 3) Default pull value If right sidebar is present, subtract 3 from default pull value
NineSixty in action
‣ Visit http://ninesixty.fkdemos.com to see how
NineSixty...
‣ uses push and pull classes to generate
content-first layout
‣ dynamically assigns grid widths based on
context
Implementing a
grid-based layout
When not to use a grid
‣ Implementing a grid will probably be impossible if
your site’s layout...
‣ uses irregular column sizes
‣ has irregular margins or gutters
‣ Implementing a grid will be difficult — but not
impossible — if your site’s layout...
‣ has gutter widths of odd numbers
‣ is fluid
Getting started
‣ Do not change the NineSixty theme on your site!
‣ Hacking NineSixty is like hacking core: It will
make upgrading your site very difficult
‣ Instead, subtheme NineSixty or create a totally
Subtheme
‣ This method is best if your site is (or can be)
960px wide and can utilize 12 or 16 columns
‣ Subtheming instructions and resources on
Drupal.org:
‣ Subtheming quick and dirty
Build a new theme
‣ You should build a new theme when your site’s
layout...
‣ isn’t 960px wide
‣ doesn’t use 12 or 16 columns
‣ It’s more efficient to use a new theme than to
Image source: Client project
Do the math
‣ Be prepared to crunch numbers
‣ Building a new theme can be very confusing
‣ Spreadsheets can help you visualize column,
‣ Examples (remember that the true “canvas” size of
960.gs is actually 940px):
‣ (940 - ((12 - 1) x 20)) ÷ 12 = 60
‣ (940 - ((16 - 1) x 20)) ÷ 16 = 40
Source: Grids are Good by Khoi Vinh and Mark Boulton
The grid equation
Four Kitchens’ company
website
Source: fourkitchens.com
‣ Subtheme of NineSixty
Source: fourkitchens.com/blog Right column grid-3 Header promos grid-4 Content column grid-8 Gutter grid-1
Source: fourkitchens.com Right column grid-3 Content column grid-8 Gutter grid-1 Footer columns grid-3 Sub-footer right column grid-3 Sub-footer content column grid-8 Gutter grid-1
Learn more about grids
‣ The Grid System
‣ “The ultimate resource in grid systems”
‣ The Grid System’s Flickr pool
Downloads
‣ 960 grid system: 960.gs
‣ NineSixty theme for Drupal: drupal.org/project/
ninesixty
‣ This and other presentations are available for
Credits
‣ “History of the grid” slides were
borrowed heavily from Khoi Vinh and Mark Boulton’s presentation Grids are Good and from
Wikipedia
‣ Piet Mondriaan painting was found
somewhere online. Copyright holder is unknown
‣ The items listed above are exempt
from this presentation’s Creative Commons license
‣ This presentation was created and
delivered by Todd Ross Nienkerk, co-founder of Four Kitchens
All content in this presentation, except where noted otherwise, is Creative Commons Attribution-ShareAlike 3.0 licensed and copyright 2009 Four Kitchen Studios, LLC.