with CSS Pre-Processors

Mo’ Classes, Mo’ Problems

Once you’ve put your classes in place and you’ve got the basic shell-interface doing what you want, additions and design changes start rolling in. They should all be just like what you’ve done, but just a little different. Just move that box over there at this breakpoint, move this over here… that can’t be hard — right? It took the designer only 5 minutes to do it in Illustrator!

.some-selector.pull-left {
@media (max-width: @screen-sm-max) {
float: none;
}
}
.btn.btn-primary.btn-lg.btn-block {
@media (min-width: @screen-md) {
display: inline-block;
width: auto;
}
}
Look how helpful Foundation is being!
text-align: [direction] !important;
Definitely not a sidebar

Your Tools Are (only slightly) Dark and Full of Terrors

Contrary to how all this may sound, I’m actually a big proponent of frameworks. I think in addition to being a common vernacular for teams to use to talk about developing an interface, they can be great learning tools.

The droids you are looking for

What if I told you there is a way to have our markup stay super clean and just have our semantic markup point to our visually described utility classes?

A modified layout from Yahoo Pure’s website
<div class="pure-menu pure-menu-open pure-menu-horizontal">
<a href="#" class="pure-menu-heading">Your Logo</a>
<ul>
<li><a href="#">Home</a></li>
<li class="pure-menu-selected"><a href="#">Blag</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>
<nav>
<a href="#">Your Logo</a>
<ul>
<li><a href="#">Home</a></li>
<li class="active"><a href="#">Contact</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
<div class="pure-menu pure-menu-open pure-menu-horizontal">
<a href="#" class="pure-menu-heading">Your Logo</a>
<ul>
<li><a href="#">Home</a></li>
<li class="pure-menu-selected"><a href="#">Blag</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>
@import (reference) ‘base.less’;
@import (reference) ‘buttons.less’;
@import (reference) ‘grids.less’;
@import (reference) ‘grids-responsive.less’;
@import (reference) ‘buttons.less’;
@import (reference) ‘menus.less’;
@import (reference) ‘forms.less’;
@import (reference) ‘tables.less’;
[...]
button { 
&:extend(.pure-button all);
&:extend(.pure-button-primary all);
}
button:extend(.pure-button all, .pure-button-primary all) {}
body > nav {
&:extend(.pure-menu all);
&:extend(.pure-menu.pure-menu-horizontal all);
&:extend(.pure-menu-open all);
> a {
&:extend(.pure-menu .pure-menu-heading all);
&:extend(.pure-menu.pure-menu-horizontal .pure-menu-heading);
&:extend(.pure-menu.pure-menu-horizontal > .pure-menu-heading all);
margin-top: 0;
}
> ul {
&:extend(.pure-menu.pure-menu-horizontal > ul all);

li {
&:extend(.pure-menu-horizontal li all);
}
.active a {
&:extend(.pure-menu .pure-menu-selected a);
}
}
}
.featured-items,
.feature-descriptions {
&:extend(.pure-g all);
max-width: 980px;
margin: 0 auto;
}
.featured-items > div,
.feature-descriptions > div {
&:extend(.pure-u-1 all);
}
.featured-items > div {
&:extend(.pure-u-md-1–3 all);
}
Horizontal Row at md breakpoint and above
Grid at sm breakpoint
Block at xs breakpoint
// Core variables and mixins
@import (reference) "../node_modules/bootstrap/less/variables.less";
@import (reference) "../node_modules/bootstrap/less/mixins.less";
// Reset and dependencies
@import (reference) "../node_modules/bootstrap/less/normalize.less";
@import (reference) "../node_modules/bootstrap/less/print.less";
@import (reference) "../node_modules/bootstrap/less/glyphicons.less";
// Core CSS@import (reference) "../node_modules/bootstrap/less/scaffolding.less";
@import (reference) "../node_modules/bootstrap/less/type.less";
@import (reference) "../node_modules/bootstrap/less/code.less";
@import (reference) "../node_modules/bootstrap/less/grid.less";
@import (reference) "../node_modules/bootstrap/less/tables.less";
@import (reference) "../node_modules/bootstrap/less/forms.less";
@import (reference) "../node_modules/bootstrap/less/buttons.less";
// Components
@import (reference) "../node_modules/bootstrap/less/component-animations.less";
@import (reference) "../node_modules/bootstrap/less/dropdowns.less";
@import (reference) "../node_modules/bootstrap/less/button-groups.less";
@import (reference) "../node_modules/bootstrap/less/input-groups.less";
@import (reference) "../node_modules/bootstrap/less/navs.less";
@import (reference) "../node_modules/bootstrap/less/navbar.less";
[...and so on...]
<div class="outer-wrapper">
<section class="my-content-wrapper">
<div>
<img src="http://placesheen.com/300/300" />
<button>Button</button>
</div>
<div>
<img src="http://fillmurray.com/300/300" />
<button>Button</button>
</div>
<div>
<img src="http://nicenicejpg.com/300/300" />
<button>Button</button>
</div>
<div>
<img src="http://placecage.com/300/300" />
<button>Button</button>
</div>
</section>
</div>
@import 'bootstrap';
@import (reference) 'compiled-grid';
* {
box-sizing: border-box;
}
img:extend(img all) {
display: block;
height: auto;
margin: 1em auto;
max-width: 100%;
}
button:extend(.btn, .btn-primary) {}.outer-wrapper:extend(.container-fluid all) {}.my-content-wrapper:extend(.row all) {
> div:extend(.col-xs-12 all, .col-sm-6 all, .col-md-3 all) {
text-align: center;
}
}

Considerations and hacks

In our previous example where we were using Pure, everything originally came from plain old CSS so the grid system was all spelled out for us. Simply renaming the file-extensions to .less and importing them with the (reference) option gave us clean access to whatever grid classes we wanted to extend. In Bootstrap’s LESS files the grid is generated from mixins (if you are unsure of what I mean, look in the mixins folder at grid.less and grid-framework.less), so those classes don’t really exist yet and therefore can’t be extended without using those mixins somewhere first.

@import (reference) "../node_modules/bootstrap/less/variables.less";
@import (reference) "../node_modules/bootstrap/less/mixins.less";
@import (reference) "../node_modules/bootstrap/less/grid.less";

I‘m a Senior Interactive Developer at Isobar International — Chicago, an Ember/Sails.js nerd, and a musician. I bake, but do no butchering or candlestick making

I‘m a Senior Interactive Developer at Isobar International — Chicago, an Ember/Sails.js nerd, and a musician. I bake, but do no butchering or candlestick making