Upload
russ-weakley
View
19.428
Download
2
Tags:
Embed Size (px)
DESCRIPTION
An introduction to the changing world of CSS. Slides from Brisbane Web Designer Meetup 13 March 2013.
Citation preview
CSSoocss, smacss & more...
what’s wrong with
CSS
CSS is simple... It’s simple to
understand. But CSS is not
simple to use or maintain.
“
”http://chriseppstein.github.com/blog/2009/09/20/why-stylesheet-abstraction-matters/
If you’ve ever worked on a medium to large website, you have probably come across a range of issues with CSS.
Issues
Lots of floats, font-size references, heading levels repeated...
Repetition
It may have started out well, but it has become a mess?
Unmanageable
You need to add some CSS - so you have to start adding to selectors in order to win.
Weight war
Your CSS is specifically tied to HTML or location...
Coupling
Developers have been telling us for years that “CSS sucks”. We all know it’s time for our CSS practices to evolve.
CSS sucks!
Luckily, there are a wide range of exciting new developments to explore.
New stuff!
Before we start... put aside any biases. At least until after the presentation, when you can rip into me :)
Biases aside...
oocssobject oriented css
What is OOCSS?
In 2009, Nicole Sullivan introduced a new way of looking at CSS. She defined this as Object Oriented CSS (OOCSS).
After optimising Facebook’s CSS, she discovered some amazing statistics... about how we reapply CSS properties throughout our style sheets.
Statistics
Facebook:Facebook blueUnique colors
colors
Salesforce:padding
h1-h6
261548
6,498
3,668511
“We have been doing it all
wrong.... Our best practices are
killing us”
Nicole Sullivan
“
”
The purpose of OOCSS is to
encourage code reuse and,
ultimately, faster and more
efficient stylesheets that are
easier to add to and maintain.
http://coding.smashingmagazine.com/2011/12/12/an-introduction-to-object-oriented-css-oocss/
“
”
Looking for patterns - rows
One of the key aims of OOCSS is to abstract as many components of the layout as possible.
Abstraction
Can you see any repeating visual patterns?
Example
The first layout pattern could be the rows.
Rows
row
row
row
row
row
row
row
row
In the past, people may have styled these rows using a series of IDs.
Past practice
#header
#main
#news
#footer
1. use a single class so that it can be reused as needed2. abstract the module down to core purposes
OOCSS aims
These rows have two purposes:1. clear each row2. trigger the block formatting context.
Core purposes
.row
.row
.row
.row
Then we can write one simple, but very powerful class that can be reused anywhere in the layout.
Re-use
.row {! clear: left;! overflow: hidden;! zoom: 1;! _overflow: visible;}
IE6 underscore hack
Triggers haslayout in IE5-7
Triggers block formatting
Clears each row
Different rows
Did you notice that two of the rows were different? They have different background colours and additional padding above and below.
Different rows
We could now add some classes based on the purpose of these rows - such as “news” and “footer”.
New names?
.news {! padding: 1em 0;! background-color: blue;!}
.footer {! padding: 1em 0;! background-color: pink;!}
However, it would be better to abstract these names further so that they are more flexible.
Abstract
.row {! clear: left;! overflow: hidden;! zoom: 1;! _overflow: visible;}
.row-alt1 {! padding: 1em 0;! background-color: blue;!}
.row-alt2 {! padding: 1em 0;! background-color: pink;!}
<div class="row"></div><div class="row"></div><div class="row row-alt1"></div><div class="row row-alt2"></div>
If you wanted, these could be abstracted even further into padding and backgrounds as separate concepts.
Further
.row-padding {! padding: 1em 0;}
.bg-color1 {! background-color: blue;!}
.bg-color2 {! background-color: pink;!}
<div class="row"></div><div class="row"></div><div class="row row-paddingbg-color1"></div><div class="row row-paddingbg-color2"></div>
It depends on the site and circumstances as to how far you think you need to abstract these concepts.
Up to you
The row module
The “row” class is our primary module. The additional classes are “modifiers” as they modify the primary class.
Primary module
Modifiers should not rewrite any aspect of the primary module, they only modify or add to the primary module.
Modifiers
Primary module
.row-alt1
Sub-module Modifier
.row-alt1
Types of class
Looking for patterns - columns
The second layout pattern could be the columns. The wide layout looks like it has four columns.
Columns
Column 1 Column 2 Column 4Column 3
Some of the rows spread across all columns. Others spread across two or one column.
Patterns
4 columns
2 columns
2 columns
1 columns
2 columns
2 columns
1 columns 1 columns1 columns
Column 1 Column 2 Column 4Column 3
To be safe, we should assume we need containers for 4, 3, 2 and 1 column widths. We can convert these column options into a simple grid framework.
Framework 1
Wide layout4 column box 3 column box2 column box1 column box
Class names.w-4col .w-3col .w-2col .w-1col
<div class="row">! <div class="w-4col"></div></div><div class="row">! <div class="w-2col"></div>! <div class="w-2col"></div></div><div class="row row-alt1">! <div class="w-2col"></div>! <div class="w-2col"></div></div><div class="row row-alt2">! <div class="w-1col"></div>! <div class="w-1col"></div>! <div class="w-1col"></div>! <div class="w-1col"></div></div>
The same is true of the narrow layout, except this time it has only two overall columns.
Narrow
Column 1 Column 2
2 columns
1 columns 1 columns
1 columns 1 columns
1 columns 1 columns
We could also create a second, different grid for narrow screen. This would allow us to control whether columns sat beside each other or below at a narrower screen size.
Framework 2
Narrow layout2 column box 1 column box
Class names.n-2col .n-2col
<div class="row">! <div class="w-4col"></div></div><div class="row">! <div class="w-2col n-2col"></div>! <div class="w-2col n-2col"></div></div><div class="row row-alt1">! <div class="w-2col n-2col"></div>! <div class="w-2col n-2col"></div></div><div class="row row-alt2">! <div class="w-1col n-2col"></div>! <div class="w-1col n-2col"></div>! <div class="w-1col n-2col"></div>! <div class="w-1col n-2col"></div></div>
With these two simple grids, we can control complicated layouts - both wide and narrow.
Control!
Looking for patterns - boxes
You may have noticed that there were also a series of smaller boxes, each with an image to the left or right.
Boxes?
1. contain content2. feature object to left or right3. content beside feature object4. margin below
Core purpose
Adaptable boxWe need to create an adaptable box:- could be placed anywhere- any width or height- any feature content- feature content could be left/right- any content inside the body
We need to be able to target - the overall box- the object (left or right)- the body content within the box- a possible heading (h1-h6)- possibly even the contents itself
Target
This is a headingLorem ipsum dolor sit amet consect etuer adipi scing elit sed diam nonummy nibh euismod tinunt ut laoreet dolore magna aliquam erat volut.
box
box feature
box bodybox heading
box content
.box { }
.box-feature { }
.box-feature-alt { }
.box-body { }
.box-heading { }
.box-content { }
There are a range of possible class we could use here.
Do not give the box a width - allow it to spread to fit the width of any parent container.
Width
This box module must contain (and therefore wrap around) either a left or right floating object. We can solve this by triggering the block formatting context on the parent.
Contain floats
.box {! overflow: hidden;! zoom: 1;! _overflow: visible;! margin-bottom: 1em;}
Triggers block formatting
The box must work when placed anywhere within the layout. The box must be “location agnostic”.
Location Agnostic
aside .box { }.box { }
The box may contain objects that have varying widths. We need our content box (“box-body”) to sit beside these objects, regardless of their widths.
Sit beside
We can solve this by triggering the block formatting context on the “box-body” class.
BFC again
This is a headingLorem ipsum dolor sit amet consect etuer adipi scing elit sed diam nonummy nibh euismod tinunt ut laoreet dolore magna aliquam erat volut.
box-body
.box-body {! overflow: hidden;! zoom: 1;! _overflow: visible;}
Triggers block formatting
The box module
We have just made a very powerful box. Nicole Sullivan refers to this box as the “media” element.
Powerful box
.box,.box-body {! overflow: hidden;! zoom: 1;! _overflow: visible;}
.box { margin: 0 0 10px; }
.box-feature {! float: left;! margin: 0 10px 0 0;}
.box-feature-alt {! float: right;! margin: 0 0 0 10px;}
In this case, the “box” class is our primary module. There are no modifiers, but there are a range of sub-modules.
Primary module
Sub-modules are other classes associated with the primary module. They do not alter or add directly to the primary module.
Sub-modules
Types of classPrimary module
.row-alt1
.box
Sub-module
.box-feature
.box-body
Modifier
.row-alt1
Moving forward
For years, we have been taught to keep our markup clean and only use “semantic” class names.
Semantic classes
OOCSS seems to break both of these rules - and in a big way. But have we been thinking about “semantic” class names in the wrong way?
Break the rules?
HTML class names offer no
semantic value to search engines
or screen readers, aside from
microformats.
http://www.brettjankord.com/2013/02/09/thoughts-on-semantic-html-class-names-and-maintainability/
“
”
Rather than concerning
ourselves with creating semantic
class names, I think we should be
thinking about creating sensible
class names. Sensible class
names offer semantics, but they
also offer flexibility/reusability.
http://www.brettjankord.com/2013/02/09/thoughts-on-semantic-html-class-names-and-maintainability/
“
”
If your class is called “blue” and
you want to change it to red, you
have far bigger problems than
class names to deal with!
https://speakerdeck.com/andyhume/css-for-grown-ups-maturing-best-practises
“
”
In order to move forward, especially on large scale sites, we cannot keep using old practices.
Move forward
OOCSS offers front end developers an alternative - light weight, modular CSS that can be re-used repeatedly across sites.
Solution?
smacsscss architecture
What is SMACSS?
SMACSS is more style guide than
rigid framework - an attempt to
document a consistent approach
to site development when using
CSS.
http://alistapart.com/article/frameworksfordesigners
“
”
In 2011, Jonathan Snook introduced a new way of looking at CSS architecture. He called this Scalable and Modular Architecture for CSS (SMACSS)
Categorization
Base rulesLayout rulesModule (and sub-module) rulesState rulesTheme rules
Categories
Base rules are the defaults. They are almost exclusively single element selectors.
Base
Layout rules divide the page into sections. Layouts hold one or more modules together.
Layout
Modules are the reusable, modular parts of our design. They are the callouts, the sidebar sections, the product lists and so on.
Modules
SMACSS allows for primary modules, modifiers and sub-modules, though they are labelled slightly differently.
Primary module
.row-alt1
.box
Sub-moduleSub-component
.box-feature
.box-body
ModifierSub-module.row-alt1
State rules are ways to describe how our modules or layouts will look when in a particular state. Is it hidden or expanded?
States
Theme rules describe how the layout or modules might look.
Themes
Naming Convention
Use classes rather than IDs for styling purposes. Classes are more flexible. Using classes can reduce specificity issues.
Avoid IDs
Class names should be meaningful for other authors, so that other developers can understand their purpose.
Meaningful
Class names should follow understandable patterns.
Pattern
Use “pseudo-namespaces” as prefixes - so that modules, modifiers and sub-modules can be identified.
Prefixes
Possibly use different naming conventions for modifiers, sub-modules and states.
.example-widget { }
.example-widget--modifier { }
.example-widget__sub-module { }
.example-widget--is-somestate { }
Modifiers
Decouple HTML/CSS
I’ve noticed that designers
traditionally write CSS that is
deeply tied to the HTML that it is
designed to style. How do we
begin to decouple the two for
more flexible development with
less refactoring?
http://coding.smashingmagazine.com/2012/04/20/decoupling-html-from-css/
“
”
So how do we “decouple” our HTML and CSS.1. using additional class names2. using child selectors
Decouple
To see this in action, let’s look at the “box” example from earlier. What if we wanted to style the heading inside the “box-body”.
Example
This is a headingLorem ipsum dolor sit amet consect etuer adipi scing elit sed diam nonummy nibh euismod tinunt ut laoreet dolore magna aliquam erat volut.
heading
We could style this heading using something like this:
.box { }
.box h2 { }
Style the h2?
<div class="box">! <img class="box-feature"! src="dummy-140.png" alt="">! <div class="box-body">! ! <h2>Heading</h2>! ! </p>Lorem ipsum dolor</p>! </div></div>
The problem is that the CSS is “coupled” with the HTML. What happens if there is an <h3> element inside the box?
Problem?
One solution would be to set all heading levels.
.box { }
.box h1 { }
.box h2 { }
.box h3 { }
.box h4 { }
.box h5 { }
.box h6 { }
However, the safest way to “uncouple” the CSS and HTML would be to use a simple class.
Use a class
<div class="box">! <img class="box-feature"! src="dummy-140.png" alt="">! <div class="box-body">! ! <h2 class="box-heading">! ! ! Heading</h2>! ! </p>Lorem ipsum dolor</p>! </div></div>
Now our HTML and CSS are more flexible. It doesn’t matter what heading level is used.
.box { }
.box-heading { }
More flexible
modulesa closer look at
The following “module” guidelines apply regardless of whether you are coming from OOCSS or SMACSS.
Guidelines
Rule 1: keep modules simple
By making your base objects this
simple your choices become
boolean; you use the object or
you don’t. The object is either
entirely suitable as a basis, or
entirely _un_suitable.
http://csswizardry.com/2012/06/the-open-closed-principle-applied-to-css/
“
”
The base module should be defined as simply as possible. This means that they are highly flexible.
Keep ‘em simple
Let’s use an example of our “row” class. What if we added some padding to this rule?
.row {! clear: left;! overflow: hidden;! padding: 20px 0;}
But what if we want a row that doesn’t have padding? The problem is that this rule is now very specifically defined. It is therefore not as flexible.
Rule 2: don’t undo styles
Any CSS that unsets styles (apart
from in a reset) should start
ringing alarm bells... Rulesets
should only ever inherit and add
to previous ones, never undo.
http://csswizardry.com/2012/11/code-smells-in-css/
“
”
Leading on from the first rule, you should avoid writing rules to undo a previous module.
Don’t undo
For example, what if you wanted almost all of your headings to have a border-bottom?
h2 {! font-size: 1.5em! margin-bottom: 1em;! padding-bottom: 1em;! border-bottom: 1px solid red;}
But in some cases you might want a heading without a border-bottom.
You could write a new rule like this:
.no-border {! padding-bottom: 0;! border-bottom: none;}
This is not ideal. It is much better to write sub-modules that add styles, rather than write sub-modules to undo styles.
So, a better way might be to write two rules like this:
/* default style */h2 {! font-size: 1.5em! margin-bottom: 1em;}
/* only when border needed */.headline {! padding-bottom: 1em;! border-bottom: 1px solid red;}
Rule 3: extend but don’t
modify
Base modules can be extended using sub-modules. However, the base module itself should never be modified.
Don’t modify
This is based on the object oriented programming “open/close principle”.
Software entities (classes,
modules, functions, etc.) should
be open for extension, but closed
for modification.
http://en.wikipedia.org/wiki/Open/closed_principle
“
”
If a based module needs to be modified to suit a specific case, it is probably better to create a new module.
Rule 4: think before adding
new modules
It is always tempting to add a module based on your need at the time... as well as based on the needs of the system.
Don’t rush
This often happens after the initial planning and build has been done. It’s easy to be tempted by “I’ll just drop this new class in at the bottom of my CSS”.
However, adding poorly structured new modules, without rigorous abstraction, will lead to bloated, hard-to-manage CSS.
practicescoding
Comment conventions
There is a growing trend to use the DocBlock as an overall comment convention. In fact, a movement around this type of commenting began over 6 years ago with the CSSdoc group
DocBlock
"A DocBlock is an extended C++-
style PHP comment that begins
with "/**" and has an "*" at the
beginning of every line.
DocBlocks precede the element
they are documenting...
http://en.wikipedia.org/wiki/PHPDoc
“
”
/** * Short desc * * Long description first sentence starts * and continues on this line for a while * finally concluding here at the end of * this paragraph * * The blank line above denotes a paragraph */
Formatting CSS rules
In the early days of CSS, a lot of developers preferred single line CSS rules as they could easily see the selectors.
Single line?
Today, with the complexity of individual rules, most developers seem to prefer either the multi-line format, or multi-line with indenting format.
Multi-line
Multi-line Format with IndentingMulti-line FormatSingle-line FormatSingle-line Format with Indenting/TabbingMostly Single-line FormatSingle-line Format with TabbingOther
44%28%11%5%5%4%3%
*CSS-tricks poll: http://css-tricks.com/different-ways-to-format-css/
CSS Tricks rule formatting poll
.navigation_rss_icon {! position: absolute;! left: 940px;! bottom: 0px;}
#navigation_rss {! position: absolute;! left: 720px;! font-family: Verdana, Arial, Helvetica, sans-serif;! text-transform: uppercase;! color: #897567;! line-height: 2.5em;}
#navigation_rss li {! display: inline;}
#navigation_rss li a:link, #navigation_rss li a:visited {! color: #fffffe;! text-decoration: none;! padding: 0px 2px;! letter-spacing: -0.05em;}#navigation_rss li a:hover {! color: #eed2a1;! text-decoration: none;}
.navigation_rss_icon { position: absolute; left: 940px; bottom: 0px;}
#navigation_rss { position: absolute; left: 720px; font-family: Verdana, Arial, Helvetica, sans-serif; text-transform: uppercase; color: #897567; line-height: 2.5em;}
#navigation_rss li { display: inline; }
#navigation_rss li a:link, #navigation_rss li a:visited { color: #fffffe; text-decoration: none; padding: 0px 2px; letter-spacing: -0.05em; }
Declaration order
Similarly, many developers used to prefer to sort their declarations alphabetically.
Alphabet?
Today, most people prefer to group their declarations by type.
Group
Grouped by type 45%Random - 39%Alphabet - 14%By line - 2%
45%39%14%2%
*CSS-tricks poll: http://css-tricks.com/different-ways-to-format-css/
CSS Tricks declaration formatting poll
.selector { /* Positioning */ position: absolute; z-index: 10; top: 0; right: 0;
/* Display & Box Model */ display: inline-block; overflow: hidden; box-sizing: border-box; width: 100px; height: 100px; padding: 10px; border: 10px solid #333; margin: 10px;
/* Color */ background: #000; color: #fff /* Text */ font-family: sans-serif; font-size: 16px; line-height: 1.4; text-align: right;
/* Other */ cursor: pointer;}
Of course, many tools and pre-processors take care of this for you. If your tools do not have this capability, take a look at CSS Combhttp://csscomb.com/
get busy!
Russ WeakleyMax Design
Site: maxdesign.com.auTwitter: twitter.com/russmaxdesignSlideshare: slideshare.net/maxdesignLinkedin: linkedin.com/in/russweakley