WYNNNETHERLAND COMPASS, SASS, AND THE ENLIGHTENED WEB
Jan 27, 2015
WYNNNETHERLAND
COMPASS, SASS, AND THE ENLIGHTENED WEB
whoami
+
Native Oklahoman
Naturalized Texan
or “Okie” in the local vernacular.
Like you, I work on the Interwebs.
... but my story begins in
theDARK AGES
Literally.
this still works :brew install lynx
gopher:// look it up, kids.
anyone?
Flight of the Navigator
technology from the future!
These were perilous times.
Full of strange magic.
<font>
<center>
<blink>
<table> <tr> <td valign=top>Remember this?</td> <td> <table> <tr> <td>And this?</td> </tr> </table> </td> </tr> </tr></table> Nested tables FTW.
JavaScript vs. JScript
Sometimes we’d hide these andupdate the page without a refresh, backwhen Ajax was something Momma used toclean the bathtub.
DOM level 0.
document.formName.inputName
Why am I sharing all this?
Consider it inoculation against
CURMUDGEONRY.
THAT’S THEWAY IT WAS AND
WE LIKED IT.
“GET OFF MY LAWN.”
Nathan SmithCreator, 960.gsRefreshOKC headlinerReformed Curmudgeon
Back to our story
theRENAISSANCE
JavaScript Frameworks
CSS Frameworks
HTML5
CSS3
border-radius
border-image
www.zurb.com/playground/awesome-overlays
background-size
gradients
RGBA, HSL, HSLA colors
rgba (0,0,0,1) is the new black!
text-shadow
box-shadow
wordwrap
outline
columns
@font-face
Typographic freedom!
means
New selectorsCool
* E
.class #id E F
E > F E + F
E[attribute] E[attribute=value] E[attribute~=value] E[attribute|=value]
:first-child :link
:visited :lang() :before ::before :after ::after
:first-letter
::first-letter :first-line ::first-line
E[attribute^=value] E[attribute$=value] E[attribute*=value]
E ~ F :root
:last-child :only-child :nth-child()
:nth-last-child() :first-of-type :last-of-type :only-of-type :nth-of-type()
:nth-last-of-type() :empty :not() :target
:enabled :disabled :checked
CSS3 selectors (and some golden oldies)
:header
Steal this from jQuery, please
This is not a talk about CSS
Follow @smashingmag for your CSS tips & tricks
REAL stylesheet innovationI want to talk about
HOW we write stylesheetsI want to talk about
how we MAINTAIN stylesheetsI want to talk about
how we SIMPLIFY stylesheetsI want to talk about
We're gonna see a brave new world where they run everybody a wire and hook us all up to a grid. Yes, sir, a veritable age of reason. Like the one they had in France. Not a moment too soon.
~ Ulysses Everett McGill
theAGE OF ENLIGHTENMENT
Sass
Syntax options
table.users { tr { td { background: #d1d1d; a { color: #111; } } }}
Syntax options - SCSS Sassy CSS!
table.users tr td background: #d1d1d a color: #111
Syntax options - Indented I ♥ whitespace
Nested rules
table.users tr td a {color: #111}
table.users tr.alt td a {color: #333}
Nested rules - selectors
table.users tr td a color: #111 td.alt a color: #333
Nested rules - selectorsLook, Ma,no braces
or semicolons
But you can useboth if you wanna
table.users tr td color: #111 &.alt color: #333 &:hover color: #666
Nested rules - selectors
Change this
... and you change these
.users font: size: 1.2em style: italics weight: bold
Nested rules - properties
Variables
.user { background: #333; border-size: 2px;}
.owner { background: #333; border-size: 2px;}
.admin { background: #666; border-size: 4px;}
Variables
!gray = #333!default_border = 2px
.user background: = !gray border-size: = !default_border
.owner background: = !gray border-size: = !default_border
.admin background: = !gray + #333 border-size: = !default_border + 2px
Variables
Even math!and color mixing!
Variables$font-apres: Apres, Arial, sans-serif$dark-gray: #1e1e1e !default$body-text: #bbb !default$strong-text: lighten($body-text, 40%)$muted-text: darken($body-text, 40%)$content-background: #fff$content-text: #555$content-border: #ccc$form-background: rgba(0, 0, 0, .5)
$blue-primary: #6095c2$blue-secondary: #1742db$green-primary: #64b900$green-secondary: #298527$pink-primary: #f44ab7
Mixins
.avatar { padding: 2px; border: solid 1px #ddd; position: absolute; top: 5px; left: 5px;}
p img { padding: 2px; border: solid 1px #ddd;}
Mixins
=frame(!padding_width = 2px, !border_color = #ddd) padding = !padding_width border: width: 1px style: solid color = !border_color
.avatar +frame position: absolute top: 5px left: 5px
p img +frame(1px, #ccc)
Mixins
defines the mixin
mixes in the rules
Selector inheritance
.flash { padding: 5px; border-width: 1px; font-weight: bold;}.error { color: #8a1f11; background: #fbe3e4;}.notice { color: #514721; background: #fff6bf;}
Selector inheritance
.flash padding: 5px border-width: 1px font-weight: bold
.error.flash color: #8a1f11 background: #fbe3e4
.notice.flash color: #514721 background: #fff6bf
Selector inheritance
.flash,
.error,
.notice { padding: 5px; border-width: 1px; font-weight: bold; }
.error { color: #8a1f11; background: #fbe3e4; }
.notice { color: #514721; background: #fff6bf; }
Selector inheritance
now we can use a single class in our markup
Imports
@import url(/css/reset.css)@import url(/css/typography.css)@import url(/css/layout.css)
Imports
parent + 3 @imports = 4 http requests
@import reset.sass # _reset.sass@import typography.sass # _typography.sass@import layout.sass # _layout.sass
Imports
Included at compile time - just one http request
Imports + Mixins
Now it gets fun!
@import compass/css3.sass
.callout +border-radius(5px) +linear-gradient("left top", "left bottom", #fff, #ddd)
.callout { -moz-border-radius: 5px; -webkit-border-radius: 5px; -border-radius: 5px; background-image: -moz-linear-gradient(top, bottom, from(#fff), to(#ddd)); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.00, #fff), color-stop(1.00, #ddd));}
Compass CSS3 mixins
very different syntax
css3/border_radius.sasscss3/inline_block.sasscss3/opacity.sasscss3/text_shadow.sasscss3/box_shadow.sasscss3/columns.sasscss3/box_sizing.sasscss3/gradient.sasscss3/background_clip.sasscss3/background_origin.sasscss3/background_size.sasscss3/font_face.sasscss3/transform.sasscss3/transition.sass
Compass CSS3 mixins
Bring your favorite CSS Framework
<div id='wrapper' class="container"> <div id='content' class="span-7 prepend-1"> <div id='main' class="container"> ... </div> <div id='featured' class="span-5 last"> ... </div> </div> <div id='sidebar' class="span-3 append-1 last"> ... </div></div>
A Blueprint example
boo
@import blueprint/reset.sass@import partials/base.sass@import blueprint@import blueprint/modules/scaffolding.sass
#wrapper +container #content +column(7) +append(1) #featured +column(5, true) #sidebar +column(3, true) +prepend(1)
A Blueprint example
Functions
Very. Powerful. Functions.
hue(#cc3) => 60degsaturation(#cc3) => 60%lightness(#cc3) => 50%
adjust-hue(#cc3, 20deg) => #9c3saturate(#cc3, 10%) => #d9d926desaturate(#cc3, 10%) => #bfbf40lighten(#cc3, 10%) => #d6d65cdarken(#cc3, 10%) => #a3a329
grayscale(#cc3) => desaturate(#cc3, 100%) = #808080complement(#cc3) => adjust-hue(#cc3, 180deg) = #33c
mix(#cc3, #00f) => #e56619mix(#cc3, #00f, 10%) => #f91405mix(#cc3, #00f, 90%) => #d1b72d
Sass 2.4 color functions
http://nex-3.com/posts/89-powerful-color-manipulation-with-sass
mix(rgba(51, 255, 51, 0.75), #f00) => rgba(178, 95, 19, 0.875)mix(rgba(51, 255, 51, 0.90), #f00) => rgba(163, 114, 22, 0.95)
alpha(rgba(51, 255, 51, 0.75)) => 0.75opacity(rgba(51, 255, 51, 0.75)) => 0.75
opacify(rgba(51, 255, 51, 0.75), 0.1) => rgba(51, 255, 51, 0.85)fade-in(rgba(51, 255, 51, 0.75), 0.1) => rgba(51, 255, 51, 0.85)
transparentize(rgba(51, 255, 51, 0.75), 0.1) => rgba(51, 255, 51, 0.65)fade-out(rgba(51, 255, 51, 0.75), 0.1) => rgba(51, 255, 51, 0.65)
Sass 2.4 color functions with alpha support!
http://nex-3.com/posts/89-powerful-color-manipulation-with-sass
Who makes this syntactic sugar?
Sass and CompassCSS extensions &
compilerPatterns &plugins
...like peas and carrots.
$ sudo gem install haml$ sudo gem install compass --pre
CALL IT FROM THE COMMAND LINE$ sass screen.sass screen.css
OR COMPASS-IZE YOUR PROJECT$ compass --rails -f blueprint
OR WATCH A FOLDER$ compass --watch
Sass and Compass
A quick survey of Compass
Blueprint
Blueprint★ Buttons
★ Colors
★ Debug
★ Fancy Type
★ Form
★ Grid
★ Interaction
★ Internet Explorer
★ Link Icons
★ Liquid
★ Reset
★ Rtl
★ Scaffolding
★ Typography
★ Utilities
CSS3
CSS3★ Appearance
★ Background Clip
★ Background Origin
★ Background Size
★ Border Radius
★ Box
★ Box Shadow
★ Box Sizing
★ CSS3 Pie
★ Columns
★ Font Face
★ Gradient
★ Images
★ Inline Block
★ Opacity
★ Shared Utilities
★ Text Shadow
★ Transform
★ Transform (legacy)
★ Transition
Image sprites
@import "icon/*.png"
.actions .new +icon-sprite(new) .edit +icon-sprite(edit) .save +icon-sprite(save) .delete +icon-sprite(delete)
Image sprites
.icon-sprite,
.actions .new,
.actions .edit,
.actions .save,
.actions .delete { background: url('/images/icon-34fe0604ab.png') no-repeat; }
.actions .new { background-position: 0 -64px; }
.actions .edit { background-position: 0 -32px; }
.actions .save { background-position: 0 -96px; }
.actions .delete { background-position: 0 0; }
@import "icon/*.png"
public/images/icon/new.pngpublic/images/icon/edit.pngpublic/images/icon/save.pngpublic/images/icon/delete.png
1.2.
3.
I like the Sprite in you®
URL helpers
#nav background: image-url("nav_bg.png") repeat-x top center
DEVELOPMENT#nav { background: url("/images/nav_bg.png") repeat-x top center;}
PRODUCTION#nav { background: url("http://assets.example.com/images/nav_bg.png") repeat-x top center;}
URL helpers
relative paths for development,
absolute for production
stylesheet-url($path)
font-url($path)
image-url($path)
URL helpers
Share your patterns
http://brandonmathis.com/projects/fancy-buttons/
@import "fancy-buttons"button,a.button +fancy-button(#2966a8)
compass-960
$ninesixty-columns: 16
#wrap +grid-container #left-nav +alpha +grid(5) #main-content +grid-prefix(1) +grid(10) +omega
Compass 960
https://github.com/chriseppstein/compass-960-plugin
compass-wordpress
$ gem install compass-wordpress
CRANK OUT A NEW SASS-Y WORDPRESS THEME$ compass -r compass-wordpress \ -f wordpress -p thematic \ --sass-dir=sass --css-dir=css \ -s compressed my_awesome_theme
AUTOCOMPILE YOUR CHANGES$ compass --watch
Compass and WordPress shameless plug
compass-formalize
Announcing!
INSTALL THE GEM$ gem install compass_formalize
CREATE THE COMPASS PROJECT$ compass create my-great-app -r compass_formalize
$ cd my-great-app
APPLY THE PATTERN$ compass install formalize/jquery
Compass and Formalize
Stats
Stats| --------------------------------- | ----- | ---------- | -------------- | ----------- | --------- | -------------- || Filename | Rules | Properties | Mixins Defs | Mixins Used | CSS Rules | CSS Properties || --------------------------------- | ----- | ---------- | -------------- | ----------- | --------- | -------------- || app/stylesheets/_960.sass | 198 | 141 | 0 | 0 | -- | -- || app/stylesheets/_animation.sass | 2 | 2 | 0 | 0 | -- | -- || app/stylesheets/application.sass | 268 | 607 | 0 | 33 | 1131 | 3684 || app/stylesheets/_data_table.sass | 39 | 66 | 0 | 4 | -- | -- || app/stylesheets/_datepicker.sass | 125 | 242 | 0 | 0 | -- | -- || app/stylesheets/_formalize.sass | 82 | 78 | 0 | 4 | -- | -- || app/stylesheets/_forms.sass | 227 | 242 | 0 | 21 | -- | -- || app/stylesheets/ie.sass | 0 | 0 | 0 | 0 | 0 | 0 || app/stylesheets/_jscrollpane.sass | 20 | 43 | 0 | 0 | -- | -- || app/stylesheets/_prettify.sass | 16 | 16 | 0 | 0 | -- | -- || app/stylesheets/print.sass | 0 | 0 | 0 | 0 | 0 | 0 || app/stylesheets/_reset.sass | 111 | 18 | 0 | 0 | -- | -- || app/stylesheets/_text.sass | 27 | 18 | 0 | 0 | -- | -- || app/stylesheets/_tiptip.sass | 19 | 40 | 0 | 0 | -- | -- || app/stylesheets/_util.sass | 56 | 54 | 0 | 0 | -- | -- || app/stylesheets/_vars.sass | 0 | 6 | 2 | 0 | -- | -- || --------------------------------- | ----- | ---------- | -------------- | ----------- | --------- | -------------- || Total (16 files): | 1190 | 1573 | 2 | 62 | 1131 | 3684 || --------------------------------- | ----- | ---------- | -------------- | ----------- | --------- | -------------- |
Isn’t she Sassy, folks?
GETTHEBOOK.
sass40Save 40% and get early access!
Sadly, sass100 is not a valid code.
Resources
sass-lang.combeta.compass-style.org
wynn.fm/okc
blog: wynnnetherland.comtwitter: @pengwynnemail: [email protected]
linkedin.com/in/netherland
and thanks for having me!
grab the slides!