Showing posts with label css. Show all posts
Showing posts with label css. Show all posts

Monday, January 11, 2016

Vertical Fixed Navigation #2

Vertical Fixed Navigation

A smart vertical navigation, with round indicators that turn into labelled icons when the user interacts with them.

Our first concept of vertical fixed navigation is one of our most popular resources. This time, we tried to push this concept a little further.

The basic idea behind putting round indicators on the side of a web page, is to give a hint to the user about the number of sections she/he can go through. We think of each dot as a content chapter, with its own title. Usually, users have to hover over a dot to access the title.

In an attempt to simplify this pattern, we decided to transform the dots when the user interacts with them, by scaling them up and showing an icon + label. Users don't need to select a specific dot/item, but just move to the side, thus showing their willingness to access the navigation.

Here is a quick preview of the final result (created using After Effects):

Vertical Fixed Navigation

Icons: Nucleoapp.com

Creating the structure

Our navigation is an unordered list wrapped in a nav.cd-vertical-nav. A button.cd-nav-trigger is used to open the navigation on small devices.

Besides, a section.cd-section has been created for each navigation item.


 

 

Vertical Fixed Navigation #2

scroll down

Adding style

On small devices (viewport width smaller than 800px), we set a position: fixed for the .cd-nav-trigger and nav elements and placed them at the bottom-right corner of the page; we then scale down the navigation, using the bottom-right corner as transform origin.

When user clicks on the .cd-nav-trigger element, we give the .open class to the navigation to change its scale value from 0 to 1, with a CSS3 transition to achieve a smooth animation.

.cd-nav-trigger {
  display: block;
  position: fixed;
  z-index: 2;
  bottom: 30px;
  right: 5%;
}
 
.cd-vertical-nav {
  position: fixed;
  z-index: 1;
  right: 5%;
  bottom: 30px;
  transform: scale(0);
  transform-origin: right bottom;
  transition: transform 0.2s;
}
.cd-vertical-nav.open {
  transform: scale(1);
}

On bigger devices, we use Modernizr to detect touch and no-touch devices (using .touch and .no-touch classes).

On touch devices, the lateral navigation items (labels and icons) are visible by default, while on no-touch devices they are shown when the user hovers over the lateral navigation.

We set a fixed height and width for the nav element, and place it on the right side of the viewport. We use its ::before pseudo-element to create the navigation background; on no-touch devices only, the ::before element is, by default, translated to the right (outside the viewport) and is moved back to its original position when the user hovers over the navigation. The same happens for the span.label elements.

@media only screen and (min-width: 800px) {
  .cd-vertical-nav {
    right: 0;
    top: 0;
    height: 100vh;
    width: 90px;
  }
  .cd-vertical-nav::before {
    /* this is the navigation background */
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.8);
    transform: translateX(100%);
    transition: transform 0.4s;
  }
  .no-touch .cd-vertical-nav:hover::before, 
  .touch .cd-vertical-nav::before {
    transform: translateX(0);
  }
  .cd-vertical-nav .label {
    display: block;
    transform: translateX(100%);
    transition: transform 0.4s;
  }
  .no-touch .cd-vertical-nav:hover .label, 
  .touch .cd-vertical-nav .label {
    transform: translateX(0);
  }
}

To create the navigation item icons and dots, we use, respectively, the ::after and ::before pseudo-elements of the navigation anchor elements (a). On no-touch devices only, the ::after and ::before are scaled down by default and then scaled back up when the user hovers over the navigation.

@media only screen and (min-width: 800px) {
  .cd-vertical-nav a {
    position: relative;
    padding: 3em 0 0;
    margin: 1.4em auto;
  }
  .cd-vertical-nav a::before, 
  .cd-vertical-nav a::after {
    /* used to create the filled circle and the background icon */
    content: '';
    position: absolute;
    left: 50%;
    transition: transform 0.4s 0s;
  }
  .cd-vertical-nav a::before {
    /* filled circle */
    top: 0;
    height: 32px;
    width: 32px;
    border-radius: 50%;
    background: #eaf2e3;
    transform: translateX(-50%) scale(0.25);
  }
  .cd-vertical-nav a::after {
    /* icon */
    top: 8px;
    height: 16px;
    width: 16px;
    background: url(../img/cd-nav-icons.svg) no-repeat;
    transform: translateX(-50%) scale(0);
  }
  .no-touch .cd-vertical-nav:hover a::before, 
  .no-touch .cd-vertical-nav:hover a::after, 
  .touch .cd-vertical-nav li:nth-of-type(n) a::before, 
  .touch .cd-vertical-nav li:nth-of-type(n) a::after {
    transform: translateX(-50%) scale(1);
  }
}

Now the tricky part: when the navigation dots are scaled down, they are too distant one from the other. We can reduce this distance translating them along the Y axis.

Let's start from the central dots (in our case, the second and the third); we want to translate down the second one (so we have to use a positive translate value), while we want to translate up the third one (so we have to use a negative translate value). In our case we have:

.cd-vertical-nav li:nth-of-type(2) a::after {
    transform: translateX(-50%) translateY(1.5em) scale(0);
  }
  .cd-vertical-nav li:nth-of-type(2) a::before {
    transform: translateX(-50%) translateY(1.5em) scale(0.25);
  }
  .cd-vertical-nav li:nth-of-type(3) a::after {
    transform: translateX(-50%) translateY(-1.5em) scale(0);
  }
  .cd-vertical-nav li:nth-of-type(3) a::before {
    transform: translateX(-50%) translateY(-1.5em) scale(0.25);
  }

Then, the translate value for the first dot is gonna be three times the one of the second dot, and the same for the fourth one (three times the translate value of the third dot).

.cd-vertical-nav li:first-of-type a::after {
    transform: translateX(-50%) translateY(4.5em) scale(0);
  }
  .cd-vertical-nav li:first-of-type a::before {
    transform: translateX(-50%) translateY(4.5em) scale(0.25);
  }
  .cd-vertical-nav li:nth-of-type(4) a::after {
    transform: translateX(-50%) translateY(-4.5em) scale(0);
  }
  .cd-vertical-nav li:nth-of-type(4) a::before {
    transform: translateX(-50%) translateY(-4.5em) scale(0.25);
  }

If you have a different number of navigation items, you have to change these translate values accordingly. For example, if you have six items, starting again from the central dots (in this case, the third and the fourth), you can assign them a translateY value of 1.5 em/-1.5em; then to the second and the fifth a translateY value of 4.5em/-4.5em (3*1.5), and finally to the first and sixth a translateY value of 7.5em/-7.5em (5*1.5).

If you have an odd number of items, let's say 5, you do not translate the central one (in this case the third one). You then assign a translateY value of 3em/-3em(2*1.5) to the second and the fourth dots, and finally a translateY value of 6em/-6em(4*1.5) to the first and fifth dots.

Events handling

When user scrolls through the sections, the updateSections() function evaluates which section is currently being viewed and assigns the .activebutton.cd-nav-trigger to open/close the navigation on small devices.


Wednesday, November 25, 2015

Creating an Animated Menu Indicator with CSS Selectors

Animated Menu Indicator with CSS Selectors

In this article, I'll cover creative ways of using sibling selectors and pseudo elements to make a CSS-only menu indicator that would normally be achieved using JavaScript.

Saturday, November 07, 2015

Animated Intro Section

Animated Intro Section

A collection of fancy text effects, to animate the tagline and action buttons of your website intro section.

Animations in web design are often used to drive the user's focus to a specific section. One section you want to make sure to highlight is the main tagline, with the action buttons.

Monday, October 19, 2015

Diamond grid layout with Sass

Diamond grid layout with Sass

Since I started my career on the web, I've been building websites that follow standard grid layouts. It got to a point where I was telling an intern at my company that developers think in rectangles. I mean, there's nothing wrong with rectangular layouts. They're like your mom's Volvo, steady and reliable. But sometimes, it's fun to try something different. I'm lucky enough to work with some awesome designers, and for a new project, they came up with a diamond-based grid layout. Well then, challenge accepted. (•̀o•́)ง

Tuesday, July 07, 2015

Responsive Typography With Sass Maps

Responsive Typography With Sass Maps
Managing consistent, typographic rhythm isn't easy, but when the type is responsive, things get even more difficult. Fortunately, Sass maps make responsive typography much more manageable.

Writing the code is one thing, but keeping track of font-size values for each breakpoint is another — and the above is for paragraphs alone. Throw in h1 to h6s, each with variable font sizes for each breakpoint, and it gets cumbersome, especially when the type doesn't scale linearly.

Wednesday, June 24, 2015

Understanding CSS 3D-Transforms

Understanding CSS 3D-Transforms

3D transforms can be a bit of a mind-boggling concept at first, particularly given that the HTML canvas (your screen) is a 2D space. While most of us understand the most commonly used 3dtransform - transform: translate3d(x, y, z), there are other values that can effect 3D rendering such as rotate, backface-visibibility, perspective and lots more.

Monday, June 15, 2015

Image Tilt Effect

Image Tilt Effect

Today we'd like to share a little image effect with you. The idea is to add a tilt effect to an image by subtly moving copies of layers of semi-transparent divisions with the respective background-image. Maybe you've seen this effect already on sites like The DNA project by j.viewz, nclud or Daniel Spatzek's Website. We've implemented this effect in one of our previous demos, the Photography Website Concept, and since we've gotten a couple of requests, we thought it would be interesting to create a little plugin so that it can be easily applied to any image.

Sunday, May 03, 2015

More Control over Text Decoration

More Control over Text Decoration

Marie Mosley just finished up a revamping of the text-decoration property (and friends) in the Almanac. You're probably aware of this property. For instance, most default browser styles include underlined links by way of text-decoration: underline; - which you can remove with text-decoration: none;.

Friday, May 01, 2015

Designing Front-End Components

Designing Front-End Components

In my experience, I've found that the best pieces of code I've ever used tend to follow the UNIX philosophy of doing one thing very well. Having that kind of focused approach to front-end modules typically isn't the case. Instead, we often develop solutions that are only useful in our specific use. For example, we may put together an entrenched AngularJS directive that uses other directives or relies on data-binding provided by Angular.

What's worse, most often we don't just limit ourselves to the scope of the libraries we're currently using, but to the specific scope of the one project we're working on. This means that now our library can't be extricated from that database without considerable work. For instance, consider that one time you developed a UI component where the user would type tags in plain text and after typing a delimiter (a comma or a space), they would get visual feedback into the tag being accepted. Something like the screenshot above.


Except for the fact that, unless you found what you needed on the open web in the form of a decoupled module, we sometimes commit the crime of tightly coupling the tagging feature to the framework we're using. Or to a library. Or to our application. Or to a specific part of our application.

It would be best if were able to identify what it is that we're trying to accomplish (in this case, improve the UX on an input field for tags), isolate that into its own module, and come up with the simplest possible API. Coming up with a simple API is often a dreadful task, and in this article I'll try to put together advice and explain my thought process while designing them.

Always try and ask yourself, is this actually better for the end user or is it just more productive for me as a developer to do it this way?

A lot of the time, the former simply isn't the case.

Composability isn't just a matter of playing well with the web platform. In practice, playing well with other libraries is just as important. Getting composability right is quite hard, how are you supposed to provide support for every other library out there that may interact with things you are using in the most unexpected ways imaginable? The answer is that you're not. You are not supposed, for example, to account for libraries that arbitrarily remove DOM nodes, move them, or wrap them in some other nodes. You are, however, supposed to make sure you keep the noise your module produces to a minimum, ideally producing zero noise.

There's a number of ways you can keep the noise to a minimum. One of them involves keeping CSS in check.

Turn down the CSS

If you look closely at any of these 4 libraries, rome, insignia, horsey and dragula, you'll notice how simplistic their styling is.

Designing Front-End Components

This is decidedly intentional, and aimed at making it easier to integrate the components with whatever styles your application may have. There's a few rules I follow with regards to styling within components.

  • Shy away from inline styles
  • Always prefix your CSS classes
  • Keep styles to a minimum
  • Distribute plain CSS along with the source

These seemingly simple rules have a deeper meaning, which I'll lay out next.

Shy away from inline styles

Avoiding inline styles is crucial. Inline styles are really hard to override, leading to a lot of unnecessary !important rule-sprinkling. Most of the time, a CSS class will do a better job at grouping a set of styles together, making it easier for the developer to identify what the styles are trying to accomplish, change the component stylistically, and generally have more control over the styles of the component. Not every inline style can be avoided. Positioning styles, such as left top right and bottom, that frequently change over time have a place inline. Coincidentally, the developer is expected not to have a need for modifying these styles, where control is deferred to the library author to do as they intended.

Always prefix your CSS classes

This one should be fairly obvious. Now that we've moved most of the styles in our library to CSS classes, we'll abide by this rule to create a semantic namespace for our component's classes. If you want a deeper reasoning into the topic I suggest you read CSS: The Good Parts, which discusses best practices when it comes to writing and maintaining modular CSS.

This point seems almost trivial, why make such a big deal out of adding rd- at the beginning of every class name? What is a 2 letter prefix on every single class name going to do for me? It's probably not going to do as much for you, as a module author, since every class name will probably have the same prefix. However, when you start taking into account a few modules working in tandem, or an entire array of components working under the same application (which has plenty of styles on its own), creating faux namespaces via prefixing every class in a component becomes a glaringly obvious thing to do.

Namespaces make it faster to figure out what component a class name belongs to, help reduce class name clashes (.dialog anyone?). This not only mitigates the chance that you mess up the existing styles of an application, but it also prevents the styles of that application from unwittingly breaking those of the component.

CSS is a two way street, but with the advent of flying cars we have to be extra careful.

Keep styles to a minimum

Allowing the consumer some control over the styles in a component, and making sure those styles don't clash with others, will only have an impact as long as your component doesn't think too fancily of itself. The more styles you apply to a class name, the harder it'll be for a consumer to style that to their needs. Seriously, think about this. If you are providing me with a tag editing library, why would you include styles for round borders and a box shadow on the input? If the answer is purely stylistic (it looks great!), then chances are those styles never belonged with the library in the first place.

Overstyling components is an easy mistake to make. After all, who wouldn't want to have this sweet sweet transition when the tag input moves after a tag is edited? It just takes a line of CSS! transition: all 0.2s ease-in-out. People will surely love that. It's fine to get fancy, but always strive to make it so that if a consumer doesn't want a style, he can get rid of it with a single line of CSS. If your users need to reset a lot of CSS in order to get a component to look and feel how they need it to, that's on you.

In fewer words, there shouldn't be anything stopping the consumer from styling your component so that it perfectly blends into their designs.

Distribute plain CSS along with the source

Packaging the CSS in a component has always been a debated topic. Some argue that it should be bundled with the JavaScript, so that consumers get everything by simply including your module. Complicated solutions exist too, such as Webpack allowing you to require CSS, whatever that may mean. My preferred approach is to compile CSS in every build from whatever source code I have, which has been Stylus for a long time now. I can then distribute that CSS, along with the source *.styl file(s), directly on GitHub. Nowadays my builds create a tag on git, and publish updates to both Bower and npm.

As far as consuming these modules goes, I'll typically install them from npm, include them with Browserify, and import any CSS into my Stylus bundle. Meanwhile, other users could just take the *.css files directly, whatever floats their boat.

I asked people on Twitter what specific concerns they had regarding modular front-end component design. One of the questions I got was about how to deal with CSS, which we've just covered. The other questions were concerned with clean, well-abstracted API design, as well as effectively structuring modular code. These two go hand-in-hand.

Be the API you wish to see in the world

Even though it may not seem that way, whenever I set out to build my own component I start by scouring the web for existing, usable alternatives to writing my own. Typically this yields a mixture of things I like and things I don't like, and helps shape the ideas I have about designing an API of my own. If you sift through a few libraries that sort of do what you want, you should be able to come up with a decent set of needs and use cases other people have, and add those to your own. Once you have that, the next step involves coming up with an API that's the most common denominator for all of those use cases.

In the simplest possible use case, there should be little or no configuration involved.

When it comes to components for the front-end, I think the recipe that best fits most use cases is having an API consisting of a single function that takes a DOM element, and an entirely optional configuration object. You should be able to come up with a reasonable default behavior for your component that will just work by indicating the DOM element to use. Beyond that, a configuration object will provide the consumer with customization for the appearance of the component, as well as assist them in covering the more advanced use cases.

I think Rome is a great case study of this approach.

Designing Front-End Components

Rome just takes an HTML input, and the consumer is ready to go. Clicking on the provided element will pop a simple calendar right below the input, and the user can choose a date from the calendar. This is the most basic use case and shouldn't involve any configuration whatsoever. Therefore, it doesn't. The consumer may definitely have more advanced use cases than this. They may want to hide the time, as only the date matters to them. This is, again, a very common thing to wish for, so Rome makes sure that's easy to do: rome(input, { time: false }).

Some use cases are clearly more complicated than others, and they don't deserve a pinpointed solution such as a configuration flag, but rather a more generic solution. The example below changes the calendar so that only a certain date range is deemed valid and selectable. While an arguably advanced use case, having the ability to determine a valid date range is sure to up often enough in a date picker that being able to handle these directly as configurable options makes sense.

rome(input, { min: '2013-12-30', max: '2014-10-01' });

The most important aspect of API design is to find the right abstractions, though. Suppose a library user creates an issue because they want to allow users to choose dates in summer, spring, or autumn, but not winter. You might be thinking "well, I could just create a configuration option called seasons with an array of the valid seasons". That sounds like a perfectly acceptable solution. It meets the user's needs, and it's abstracted enough to work for any season.

You've got to ask yourself, though. Would you use such an option? Would you find it simple? Most importantly, what happens when the next user comes along asking for a way to make the second week of each month invalid? Sundays? An specific point in time? Will you add a configuration option for each of these use cases? Of course not. Will you just cater to the needs of those who better align with the needs you have today for the library? Or will you go for a more generalized approach that just determined if any given date is valid?

In the case of Rome, the answer was to create a dateValidator option that allowed consumers to determine whether any given date was valid.

rome(input, {
  dateValidator: function (d) {
    var m = moment(d);
    var y = m.year();
    var f = 'MM-DD';
    var start = moment('12-21', f).year(y).startOf('day');
    var end = moment('03-19', f).year(y).endOf('day');
    return m.isBefore(start) && m.isAfter(end);
  }
});

Yes, min and max are effectively shadowed by this option, and internally they could very well function as an alias for dateValidator. That's perfectly okay. Easy of use of an API endpoint should roughly match how frequently use cases come up in a given area.

In the same vein, you should strive to reutilize parts of the API effectively. Originally, Rome didn't have a way to "link" two calendars, a common feature enabling the user to choose a "start date" and an "end date" for some sort of event or query. Given that I already had the generic dateValidator configuration property in place I could come up with a few validators that would determine if dates are valid for a given calendar based on the selection in some other calendar. Effectively building ranges, but without changing the public API, besides exposing the validators themselves.

rome(left, {
  dateValidator: rome.val.beforeEq(right)
});

rome(right, {
  dateValidator: rome.val.afterEq(left)
});

Rome even goes as far as to provide the consumer with the ability to rename all CSS classes.

The API behind the API

Once we get past the API used to create a calendar using Rome, we get back an object containing an API of its own. This object can be used to interact with the calendar after it has been created. When following this pattern I like providing, as an starting point, a destroy method which removes any DOM elements and unbinds any event listeners produced when instantiating the component. This makes sure you play well with single page applications, highly dynamic views, and other advanced use cases. The other method I find quite necessary to include is a .find method on the public API that returns these instance API objects. Typically you'd do something like rome.find(input) and get back the calendar API associated with that input, or null if there wasn't any calendar associated to it yet.

Beyond these two methods, the API behind the API should be mostly in charge of exposing parts of the component you'll sometimes want to trigger manually. In the case of Rome, besides displaying the calendar when clicking or focusing on the input, the consumer may want to add a keyboard shortcut to display the calendar, and the API should be perfectly fine supporting that use case. Beyond these simple methods, the most crucial aspect of the API behind the API is events. Emitting a few events at important milestones, such as when a calendar is displayed or a date is selected, allows the consumer to have fine grained hooks and control over what the user does, and to manipulate the outcome of those actions every step of the way. These events could be handled through synthetic events on the DOM element itself, or using a library to convert your API into an event emitter. You can use crossvent and contra.emitter respectively for these two approaches.

I tend to keep the API behind the API really simple beyond that. Following a declarative configuration style is typically going to work wonders for your component, as there will be far less coding involved for the library consumer.

wrapping('up')

As far as keeping your code modular effectively, you should treat every function in your code the same way as we discussed for the public API itself. Strive to make it simple, to identify common patterns and use cases and abstract away just enough so that you can accommodate for the most frequent use cases in the most elegant way, and then handle the least frequent use cases a bit differently. You should try and put together methods that make logical sense. Make an effort to give functions names that are as descriptive as possible (but not too verbose), and keep everything that doesn't fit the name you gave a function in some other function.

Eventually, you should start to notice how the very methods you want to promote to public API citizenship map quite logically to what you already have. For example, when I was developing dragula I already had cancel, remove, and end methods by the time I wanted to promote them to "API behind the API" level, which made it a very natural decision to make for me.

Lastly, I'd mention that keeping the dependency count low will make your modules more attractive to the public eye, as they'll become more decoupled from everything else and easier to integrate into whatever your potential consumers are doing.

Friday, April 17, 2015

Grid Item Animation Layout

Grid Item Animation Layout

A responsive, magazine-like website layout with a grid item animation effect that happens when opening the content.

Today we'd like to share a simple animated grid layout with you. The responsive layout has a sidebar and grid items that animate to a larger content area when clicked. In the first demo the content area fills the grid (inspired by a concept by Virgil Pana) and in the second demo, the whole layout moves to the left while the grid item is expanding (inspired by this Dribbble shot by Sam Thibault).

The expanding element (which is a dummy element and not the grid item itself) is not animating in width and height but instead its original dimensions are already of the expanded size and we simply scale it down initially. By setting classes, we control the transitions of all the elements: the grid item elements' disappearance and the content elements' appearance (and vice versa when we close an opened content panel).

Grid Item Animation Layout

The layout is responsive down to mobile using a media query technique that involves setting the breakpoints based on the grid item size and the sidebar. For this we use Sass, which allows us to set these kind of variables easily. The approach we are using here is mainly mobile-first, but we also do some specific restructuring for small screens.

* Please note that this layout uses some modern techniques that involve viewport units, transitions, flexbox and other properties that will only work in modern browsers.

The second demo is a bit more experimental and it might not behave as expected in all browsers. Internet Explorer seems to have some issues with transitions on transforms that use calc().

This layout is focused on the expansion effect of the grid item and many elements are simple dummies (the loader, the filter in the top bar and the "load more" in the footer of the grid).

The main markup looks as follows:


The Sass files of this project are divided into a main style file and two partials, one for the base styles and one for the media queries. Each of the demos will have a unique style Sass file (style1.scss and style2.scss) where we initiate some variable and redefine some styles if necessary (as in demo 2). There are many ways of organizing your project in Sass; this was one convenient way to do it for these two demos. If you'd like to use one of them, make sure to refactor your style declarations. If you are not familiar with Sass, you can simply use and adjust the generated CSS files.

An example for the main demo Sass file is as follows:

$item_width: 300px;
$sidebar_width: 300px;
$color_primary: #fafafa;
$color_secondary: #fff;
$color_link: #81c483;
$anim-time: 0.5s;

@import "base";
@import "mediaqueries";

The variables needed in the base and the media queries Sass files are defined here.

Grid Item Animation Layout

The media query breakpoints are defined by the amount of items we want to be visible in the grid and the sidebar (no prefixes shown):

/* Viewport sizes based on column number and sidebar */
$viewport_xs:  $item_width + $sidebar_width; /* 1 column */
$viewport_s:  $item_width * 2 + $sidebar_width; /* 2 columns */
$viewport_m:  $item_width * 3 + $sidebar_width; /* 3 columns */
$viewport_l:  $item_width * 4 + $sidebar_width; /* 4 columns */
$viewport_xl:  $item_width * 5 + $sidebar_width; /* 5 columns */
$viewport_xxl:  $item_width * 6 + $sidebar_width; /* 6 columns */

@media screen and (min-width: $viewport_xs) {
 html, 
 body, 
 .container, 
 .main {
  height: 100vh;
 }

 .main {
  height: 100%;
  margin-left: $sidebar_width;
 }

 .content__item {
  font-size: 1em;
 }

 .grid__item {
  padding: 45px 45px 30px;
 }
}

@media screen and (min-width: $viewport_s) {
 .grid {
  display: flex;
  flex-wrap: wrap;
 }

 /* 2 columns */
 .grid__item {
  width: 50%;
  border: none;
 }

 .grid__item::before {
  top: 5px;
  right: 5px;
  bottom: 5px;
  left: 5px;
  border: 1px solid rgba(74,74,74,0.075);
  transition: opacity 0.3s;
 }

 .grid__item:hover::before,
 .grid__item:focus::before {
  border: 3px solid rgba(129,196,131,0.5);
 }

 .grid__item--loading.grid__item::before {
  opacity: 0;
 }
}

@media screen and (min-width: $viewport_m) {
 /* 3 columns */
 .grid__item {
  width: 33.333%;
 }
}

@media screen and (min-width: $viewport_l) {
 /* 4 columns */
 .grid__item {
  width: 25%;
 }
}

@media screen and (min-width: $viewport_xl) {
 /* 5 columns */
 .grid__item {
  width: 20%;
 }
}

@media screen and (min-width: $viewport_xxl) {
 /* 6 columns */
 .grid__item {
  width: 16.66%;
 }
}

/* small screen changes for sidebar (it becomes an off-canvas menu) */
@media screen and (max-width: $viewport_xs - 1px) {
 .sidebar {
  transform: translate3d(-100%,0,0);
 }
 .sidebar.sidebar--open {
  transform: translate3d(0,0,0);
 }
 .sidebar.sidebar--open ~ .main {
  pointer-events: none;
 }
 .top-bar {
  padding: 22px 15px 10px 60px;
 }
 .menu-toggle {
  display: inline-block;
 }
 .sidebar .close-button {
  opacity: 1;
  top: 15px;
  right: 15px;
  pointer-events: auto;
 }
 .title--full {
  font-size: 2em;
 }
 .content__item {
  padding: 80px 20px 40px;
 }
 .close-button {
  padding: 10px 20px;
 }
 .close-button::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  background: $color_secondary;
  border-bottom: 1px solid $color_primary;
  width: 100vw;
  height: 50px;
  pointer-events: none;
  z-index: -1;
 }
}

This technique can come in handy when dealing with grid layouts. Optimally, we'd not have that last media query at all if we want to strictly follow a mobile-first approach. But since these styles are exclusively valid only for small screens, we don't want to be redefining and overwriting styles for larger screens.

Have a look at the layout and the effect and dig into the source, we really hope you find this template useful and inspiring!

View Demo or Download the files

Tuesday, April 14, 2015

Keeping it simple: coding a carousel

coding a carousel

One of the things that drives me crazy in our "modern development" world is our fetish of over-complicating things. We build solutions, and then we add layers and layers of complexity for the sake of "making them easier to maintain". In many cases, this is a fool's errand as the layers of complexity and with them the necessary documentation make people not use our solutions. Instead, in many cases, people build their own, simpler, versions of the same thing and call it superior. Until this solution gets disputed and the whole dance happens once again.

In this article I want to approach the creation of a carousel differently: by keeping it as simple as possible whilst not breaking backwards compatibility or have any dependencies. Things break on the web. JavaScript might not be loaded, CSS capabilities vary from browser to browser. It is not up to us to tell the visitor what browser to use. And as good developers we shouldn't create interfaces that look interactive but do nothing when you click them.

So, let's have a go at building a very simple carousel that works across browsers without going overboard. You can see the result and get the code on GitHub.

The HTML structure of a carousel

Let's start very simple: a carousel in essence is an ordered list in HTML. Thus, the basic HTML is something like this:

  1. 1
  2. 2
  3. 3
  4. 4

Using this, and a bit of CSS we have something that works and looks good. This is the base we are starting from.

The basic CSS

The CSS used here is simple, but hints at some of the functionality we rely on later:

.carouselbox {
  font-family: helvetica,sans-serif;
  font-size: 14px;
  width: 100px;
  position: relative;
  margin: 1em;
  border: 1px solid #ccc;
  box-shadow: 2px 2px 10px #ccc;
  overflow: hidden;
}

.content {
  margin: 0;
  padding: 0;
}

.content li {
  font-size: 100px;
  margin: 0;
  padding: 0;
  width: 100%;
  list-style: none;
  text-align: center;
}

The main thing here is to position the carousel box relatively, allowing us to position the list items absolutely inside it. This is how we'll achieve the effect. The hidden overflow ensures that later on only the current item of the carousel will be shown. As there is no height set on the carousel and the items aren't positioned yet, we now see all the items.

coding a carousel

The carousel visuals in CSS

A lot of carousel scripts you can find will loop through all the items, or expect classes on each of them. They then hide all and show the current one on every interaction. This seems overkill, if you think about it. All we need is two classes:

  • We need a class on the container element that triggers the functional display of our carousel. This one gets applied with JavaScript as this means the look and feel only changes when the browser is capable of showing the effect.
  • We need a class on the currently visible carousel element. This is the odd one out. All the others don't need any classes.

We can hard-code these for now:

  1. 1
  2. 2
  3. 3
  4. 4

All we need to show and hide the different carousel items is to change the height of the carousel container and position all but the current one outside this height:

.active {
  height: 130px;
}

.active li {
  position: absolute;
  top: 200px;
}

.active li.current {
  top: 30px;
}

You can see this in action here. Use your browser developer tools to move the current class from item to item to show a different one.

coding a carousel

Interaction with Javascript

To make the carousel work, we need controls. And we also need some JavaScript. Whenever you need a control that triggers functionality that only works when JavaScript is executed, a button is the thing to use. These magical things were meant for exactly this use case and they are keyboard, mouse, touch and pen accessible. Everybody wins.

In this case, I added the following controls in our HTML:

  1. 1
  2. 2
  3. 3
  4. 4

Now, here is where the hard-liners of semantic markup could chime in and chide me for writing HTML that is dependent on JavaScript instead of creating the HTML using JavaScript. And they'd be correct to do so. There is nothing that stops me from wrapping this chunk of HTML in a DOM call or innerHTML write-out. However, as buttons are meant to trigger JS functionality, I think it is easier to just keep that in the HTML and allow us thus to style them with much less hassle. As a security precaution, we hide them in the non-active state and show them when the "active" class has been applied:

.active .buttons {
  padding: 5px 0;
  background: #eee;
  text-align: center;
  z-index: 10;
  position: relative;
}

.carouselbox button {
  border: none;
  display: none;
}

.active button {
  display: block;
}

.offscreen {
  position: absolute;
  left: -2000px;
}

The offscreen parts are there to explain what these buttons really mean as the triangle is not enough for some people.

All that is left to make the carousel work is the JavaScript. And here it is:

carousel = (function(){
  var box = document.querySelector('.carouselbox');
  var next = box.querySelector('.next');
  var prev = box.querySelector('.prev');
  var items = box.querySelectorAll('.content li');
  var counter = 0;
  var amount = items.length;
  var current = items[0];
  box.classList.add('active');
  function navigate(direction) {
    current.classList.remove('current');
    counter = counter + direction;
    if (direction === -1 && 
        counter < 0) { 
      counter = amount - 1; 
    }
    if (direction === 1 && 
        !items[counter]) { 
      counter = 0;
    }
    current = items[counter];
    current.classList.add('current');
  }
  next.addEventListener('click', function(ev) {
    navigate(1);
  });
  prev.addEventListener('click', function(ev) {
    navigate(-1);
  });
  navigate(0);
})();
As you can see, by relying on CSS and its built-in crawling of the DOM, there is no need for any loop whatsover. Here's what's going on in this script:
  • We grab all the HTML elements we need with querySelector.
  • We set the counter to 0 – this is the variable that keeps track of which item of the carousel is currently shown.
  • We read the amount of items in the carousel and store them in a variable – this allows us to loop the carousel.
  • We set the current item as the first one in the carousel. The current variable will contain a reference to the element currently visible. All we do when the carousel state changes is remove the CSS class from it and shift it to the other one.
  • We add the class of active to the container element to change its styling and trigger the CSS functionality explained earlier.
  • The navigate method takes a parameter called direction which defines if we should go backwards (negative values) or forwards in the carousel. It starts by removing the current class from the current carousel item, thus hiding it. We then modify the counter and make sure it doesn't go beyond the amount of items available or below 0. In each case we move to the other extreme, thus making the carousel an endless rotating one. We define the new current item and add the class to show it.
  • We apply event handlers to the buttons to navigate forwards and backwards.
  • We show the first carousel item by calling navigate with 0 as the value.
Pretty simple, isn't it? By allowing CSS to do what it is good at, our JavaScript more or less is only about keeping state and shifting classes around.

Getting fancy

The showing and hiding of the items by positioning them in a container with overflow hidden should work in any browser in use these days – even the ones who should be retired. And as all we do is add and remove CSS classes, we can now tap into the beautiful features browsers have these days. Using transition, opacity and transformation, we can add a pretty effect with a few lines of CSS:

.active li {
  position: absolute;
  top: 130px;
 
  opacity: 0;
  transform: scale(0);
  transition: 1s;
}

.active li.current {
  top: 30px;
 
  opacity: 1;
  transform: scale(1);
  transition: 1s;
}

coding a carousel
The beauty of this is that the performance handling, the timing (in case you click too fast) is handled by the browser for us. No need to count FPS or juggle timeouts. As CSS is a one-off state, this also means that browsers that do not support these features simply don't show them instead of throwing an error.

Bullet-proofing our Javascript

When a browser in use doesn't support some JavaScript feature we use, things get trickier. We get an error and things break. Thus, it makes sense to test for the things we use and move on only when there is support for them. In this code, we rely on classList and querySelector, so let's just check for this:

if (!document.querySelector || !('classList' in document.body)) {
    return false;
}

We could get much more paranoid and ensure that all the DOM elements are available before proceeding but this is overkill. If a maintainer forgets to add the carouselbox class to the main element, the error thrown is pretty obvious.

Bonus round: stacking with CSS

One last trick to mention is that if you were to stack all the elements of the carousel visually and only use opacity to blend them then there is a problem with links. You'd always get the link of the first item, no matter which one is shown.

The trick to work around that is user pointer-events: none in your CSS:

.active li {
  position: absolute;
  top: 130px;
 
  pointer-events: none;
  opacity: 0;
  transform: scale(0);
  transition: 1s;
}

.active li.current {
  top: 30px;
 
  pointer-events: auto;
  opacity: 1;
  transform: scale(1);
  transition: 1s;
}

You can see this workaround in action here.

Where to go now

The natural drive as a developer now is to enhance this to allow users to define a different starting element to show, to define lots of preset effects that can be chosen with the data attribute, to allow for non-looping carousels and to define an API to allow other components on the page to interact with the carousel. And an API to create and remove and shuffle items of the carousel. And, and and... All of these are great exercises, but let's ask ourselves: who do we do that for?

We have such amazing functionality built into the platform of the web now. Maybe it is time to stop writing the perfect generic re-usable widget and just stick with simple things and let people extend them when they need to? Who knows, by not doing the work for them, people might learn to be better coders themselves.

Tuesday, April 14, 2015

Understanding Variable Scope in Sass

Variable Scope in Sass
In this article, we'll take a deeper look at variables and variable scope in Sass. The scope of a variable describes the context within which it's defined and therefore where it's available to use.

To start, I'll cover which scopes Sass supports. Then, I'll explain two useful flags we can use to customize the value of a variable. Finally, I'll briefly present the available functions for checking whether a variable exists or not.

Sass Variable Scope

Sass supports two types of variables: local variables and global variables.

By default, all variables defined outside of any selector are considered global variables. That means they can be accessed from anywhere in our stylesheets. For instance, here's a global variable:

$bg-color: green;

On the other hand, local variables are those which are declared inside a selector. Later, we'll examine how we can customize that behavior. But for now, let's see our first example.

Here we define a mixin and then the btn-bg-color variable within it. This is a local variable, and is therefore visible only to the code inside that mixin:

@mixin button-style {
    $btn-bg-color: lightblue;
    color: $btn-bg-color;
}

Next, we can call the mixin as follows:

button { @include button-style; }

The resulting CSS:

button { color: lightblue; }

Imagine, however, that we also want to use this variable (not the mixin) in another selector:

.wrap { background: $btn-bg-color; }

This would give us the following error:

Undefined variable: "$btn-bg-color".

That was to be expected, right? We tried to access a mixin variable, which is locally scoped. Don't worry though, as mentioned above, we'll fix this issue in an upcoming section.

Nested Selectors

It's worth also mentioning that if we declare a variable inside a selector, any other nested selector can access it. Here's an example:

.wrap {
    $bg-color: red;
    &:after {
        background: lighten($bg-color, 10%);
    }
}

This compiles to:

.wrap:after { background: #ff3333; }

However, look at the example below where we define a function, then use that function along with a nested selector:

@function my-function() {
    $text-color: black;
    @return $text-color;
}
     
.wrap {
    color: my-function();
    &:after{
        background: $text-color;
    }
}

If we try to compile this, we'll get the same error discussed before. Again, that happens because we can't access the text-color variable. It isn't directly defined within the parent selector, but inside the function that our selector calls.

Variable Names

Global and local variables can have the same names. To demonstrate that behavior, we'll work on a fourth example:

$text-color: tomato;
 
@mixin button-style {
    $text-color: lime;
    color: $text-color;
}
     
@mixin link-style {
    $text-color: black;
    color: $text-color;
}

Here we've defined three different variables (text-color) with the same name. The first one is a global variable, while the other two are local.

Here are some styles making use of them:

button { @include button-style; }
a { @include link-style; }
.wrap { background: $text-color; }

And the generated CSS:

button { color: lime; }
a { color: black; }
.wrap { background: tomato; }

Is that what you were expecting?

Keep in mind that we won't see these styles unless we compile with the current version of Sass (3.4). For example, supposing that we use Sass 3.3, our CSS output would look like this:

button { color: lime; }
a { color: black; }
.wrap { background: black; }

Notice the difference in the background color of the .wrap selector. This happens because according to the earlier Sass versions (same for LibSass), if we locally redefine the value of a global variable (e.g. text-color), this will be the variable's new (global) value. So, in our example the compiled styles depend on the order we declare the variable and the mixins.

The default flag

This flag allows us to set the value of a variable in case it hasn't already been set or its current value is null (treated as unassigned). To better explain how we can take advantage of it in a real scenario, let's suppose that we have a project with the following structure:

Project-Name/
├── ...
├── css/
│ └── app.css
└── scss/
├── _config.scss
├── _variables.scss
├── _mixins.scss
└── app.scss

The app.scss file looks like this:

@import "config";
@import "variables";
@import "mixins";
     
button { @include button-style; }
 
// more styles

Let's see the contents of the partial files.

Firstly, the variables.scss file contains our variables:

$btn-bg-color: lightblue !default;
$btn-bg-color-hover: darken($btn-bg-color, 5%);
     
// more variables

Notice the default flag assigned to the btn-bg-color variable.

Secondly, the mixins.scss file includes our mixins:

@mixin button-style ($bg-color: $btn-bg-color, $bg-color-hover: $btn-bg-color-hover) {
    background-color: $bg-color;
    // more styles
    &:hover {
        background-color: $bg-color-hover;
        // more styles  
    }
}
     
// more mixins

Then, the generated app.css file will be as follows:

button { color: lightblue; }
button:hover { background-color: #99cfe0; }

So, our buttons come with default styles. But let's suppose that we want to have the option to overwrite them by applying our custom values. To do this, we can reassign the desired (default) variables in the config.scss partial file:

$btn-bg-color: chocolate;
// more variables

Setting the value of this variable to chocolate will result in ignoring the corresponding value (lightblue) that has received the default flag. Therefore, the generated CSS changes as we can see below:

button { color: chocolate; }
button:hover { background-color: #bc5e1b; }

Note: in case we haven't added the default flag to the btn-bg-color variable, our CSS would be, due to the cascading nature of CSS, as follows:

button { color: lightblue; }
// hover styles

The global flag

This second flag helps us change the scope of a local variable.

Do you remember the error we saw in our first example? Well, that happened because we tried to use the btn-bg-color variable in the .wrap selector. Let's modify our example to include this new flag. Here are the new styles:

@mixin button-style {
    $btn-bg-color: lightblue !global;
    color: $btn-bg-color;
}

button { @include button-style; }

.wrap { background: $btn-bg-color; }

As you can see below, thanks to this flag, the CSS compiles without any errors:

button { color: lightblue; }
.wrap { background: lightblue; }

The global flag is useful, but bear in mind that it's not always good practice to change a variable's scope.

Checking if a Variable Exists

Sass provides two introspection functions for testing whether a variable exists or not. We can use the variable-exists and/or global-variable-exists functions to check if our local and/or global variables exist respectively.

For example, here's a common use case where we define a variable containing the absolute path to a Google Font. Then, we choose to import that font in our stylesheets, but only if the relevant variable has been instantiated.

$google-font: "http://fonts.googleapis.com/css?family=Alegreya";

@if(global-variable-exists(google-font)) {
    @import url($google-font);
}

The result:

@import url("http://fonts.googleapis.com/css?family=Alegreya");

Conclusion

In this article, I introduced you to the concept of variable scope in Sass. To make things clearer we looked at different examples, so hopefully you now have a good understanding of how scope works. You can find all the examples of this article in this SassMeister gist.

Tuesday, April 07, 2015

CSS3 Multi-column Layouts

CSS3 Multi-column Layouts

The CSS multi-column layout uses new CSS properties which allow designers to break a layout into blocks. The two main properties which control the number of columns are: column-count and column-width.

Related Properties

  • column-width
  • column-count
  • column-gap
  • column-rule
  • column-rule-width
  • column-rule-style
  • column-rule-color
  • column-span
  • column-fill
  • columns

Degradation

Column properties are ignored by browsers which don't support them. To deal with that issue, create a single column layout for unsupported browsers and multiple columns with browsers that support them.

Note: To make sure you can use multiple columns, each property needs to be written three times: Once with the -moz prefix, once with the -webkit prefix, and once without the prefix.

Syntax

Here are some examples of how you would use the multi-column properties:

Here's how to use column-count:



Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eu augue orci. Morbi tristique a felis et varius. Sed augue nunc, cursus sed congue sit amet, mollis sed risus. Aliquam sit amet fringilla nisl. Vivamus ullamcorper odio magna, ut sagittis justo accumsan at. Donec turpis turpis, sagittis vel nisl eget, sodales ullamcorper eros. Etiam ut velit non sapien tincidunt ultrices in et nisi.

You use the column-width property to set the smallest column width. If you don't set the column-count, the browser will take over and create as many columns as necessary to fit the width. Here's the code:



Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eu augue orci. Morbi tristique a felis et varius. Sed augue nunc, cursus sed congue sit amet, mollis sed risus. Aliquam sit amet fringilla nisl. Vivamus ullamcorper odio magna, ut sagittis justo accumsan at. Donec turpis turpis, sagittis vel nisl eget, sodales ullamcorper eros. Etiam ut velit non sapien tincidunt ultrices in et nisi.

Here is an example which makes use of column-count, column-gap, and column-rule:


Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eu augue orci. Morbi tristique a felis et varius. Sed augue nunc, cursus sed congue sit amet, mollis sed risus. Aliquam sit amet fringilla nisl. Vivamus ullamcorper odio magna, ut sagittis justo accumsan at. Donec turpis turpis, sagittis vel nisl eget, sodales ullamcorper eros. Etiam ut velit non sapien tincidunt ultrices in et nisi. Phasellus fringilla quam rutrum, semper neque pretium, fermentum justo. Suspendisse convallis, purus vitae mollis semper, est justo pretium neque, sit amet convallis nisi justo vel justo. Integer vestibulum, felis vel ultricies ornare, diam risus viverra odio, at tempus elit tellus quis purus. Sed porta, eros vel vehicula sollicitudin, nisi orci maximus magna, vitae commodo dui magna nec libero.

CSS3 Multi-column Layouts

Height Balancing

With the CSS3 Column specification the browser automatically sets the column height so the content in each column are similar. That said, you might want to set the height manually using the CSS height or max-height properties and then build your layout accordingly.

Resources


Tuesday, February 24, 2015

The Problem With Raw CSS

The Problem With Raw CSS

Writing raw CSS is not a pleasure nowadays. Pure CSS has a very simple and, as a side effect, very inflexible syntax that doesn't always suited our needs in building high quality products. The overall complexity of systems are increasing day by day and modern web developers need more and that's why CSS preprocessors exist.

The Overall Structure

In order to explain what a CSS preprocessor is and why we should use this kind of tools I'll build a little demo with raw CSS. After that I'll take this further by translating it in sass, the preprocessor of our choice for this article. This demo will be big enough to see the difference between each tool. I'll try also to explain along the way some new concepts about preprocessors pretty quickly, so that you can start using those right now.

For the rest of this article I'll use this HTML structure:

...

I'll skip the repetition from the code, just to be clear. You can taste full code listing and the demo in this codepen. Later we'll discuss about implementing this demo using sass, the preprocessor we used to talk about in this article.

See the Pen yyvBVZ by Andrei Glingeanu (@andreiglingeanu) on CodePen.


Sass: Syntactically Awesome Style Sheets

Installation

We have 2 options: to use command line or a GUI application.

If you have ruby installed on your system, be it windows, osx or linux, you can type into command line this line to install sass:

gem install sass

Now you should have sass binary on your computer. You can compile a file named input.sass into corresponding output.css using command below. We have --watch switch to indicate that we want to recompile automatically as we change the input.sass file.

sass --watch input.sass:output.css

Another option will be to use a tool like Prepros to compile sass files for you. Many other options at Official Installation Page.

Nesting rules

The most used feature that preprocessor gives us is rules nesting, just like we nest elements in each other in HTML. For example, when we write a rule like this:

#main-content {
    h1 {
        em {
            text-transform: uppercase;
        }
    }
}

it will generate the following CSS:

#main-content h1 em {
    text-transform: uppercase;
}

Using variables

We can treat variables as a named container, where we can put several things. For example we can store a color in a variable and use this color in multiple places. Storing a size in a variable, be it in pixels, percents or ems, is also a good idea. Let's see a demo using variables next.

$itemBackground: #867e7e;
$itemPadding: 5px;

ul.menu {
  list-style: none;
  padding: 0;
  
  li {
    display: inline-block;

    background: $itemBackground;
    transition: background .5s ease-in;
    
    // we can use several functions to modify our colors
    // here we lighten $itemBackground by 50% in order to ensure
    // that we are able to read the text
    color: lighten($itemBackground, 50%);
    
    padding: $itemPadding;
    // we can use arithmetic operations, if variable is a number
    margin-right: $itemPadding * 2;
    
    cursor: pointer;
    font-size: 2em;
  }

}


See how I defined variable $itemBackground in order to store background color for our menu? This is a very common pattern to define our palette of colors at the top and then use this colors throughout the file by explicit name. In this way we can change all colors very easily. In this demo we also have used rules nesting.

Another trick about storing colors in variables is that we can modify them using several predefined functions like:

  • lighten
  • darken
  • saturate
  • alternate

You can see full list of them and their usage on this great resource.

Parent reference

Sometimes, when using rules nesting we need a way to reference the element inside we nest rules. Let's say we need a way to target paragraphs inside an article, but only those who have the class special. We can express it this way:

article {
    p {
        color: #333;

        &.special {
            color: #f00;
        }
    }
}

The key idea here is to use & in order to reference the current element. Sass will give us back the following css:

article p {
    color: #333;
}

article p.special {
    color: #f00;
}

We can use this trick in order to target all the pseudo elements and pseudo classes of current element together. In this demo you'll see how I target :last-child in order to give it margin-right: 0; and also how to style :hover pseudo class for lis using &.

$itemBackground: #867e7e;
$itemPadding: 5px;

ul.menu {
  list-style: none;
  padding: 0;
  
  li {
    display: inline-block;

    background: $itemBackground;
    transition: background .5s ease-in;
    
    // we can use several functions to modify our colors
    // here we lighten $itemBackground by 50% in order to ensure
    // that we are able to read the text
    color: lighten($itemBackground, 50%);
    
    padding: $itemPadding;
    // we can use arithmetic operations, if variable is a number
    margin-right: $itemPadding * 2;
    
    cursor: pointer;
    font-size: 2em;
    
        
    &:hover {
      // another function which modifies color
      background: darken($itemBackground, 10%);
    }

    &:last-child {
      margin-right: 0;
    }
  }
  

}


Mixins and extending rules

In a nutshell, mixins are a way to encapsulate many useful properties into one block, and then using @include insert this properties into our rule. This is somewhat a similar concept to functions in JavaScript and PHP. The main idea is that you can pass different parameters to the mixin, and it will return you the right properties, depending on the parameters you passed. Let's see an example where we define a mixin in order to write vendor prefixes for transform property.

@mixin transform($transformation) {
  -webkit-transform: $transformation;
  transform: $transformation;
}

div {
  width: 100px;
  height: 100px;
  background: red;

  @include transform(translate(40px));
}


Let's see, here we have transform mixin, and we include it into div, using @include. As a named parameter $transformation we receive translate(40px). The generated css for this mixin will look like this:

-webkit-transform: translate(40px);
transform: translate(40px);

Another way of reusing existing styles is to @include already existing rules. This one is not so common as mixins, because it does not have the ability to pass parameters to it, therefore it is not so flexible. You'll have an example on using this technique in the final demo for sass.

Hence, we have many ways to not repeat ourselves by defining mixins and including already existing rules. There is available online many collections of predefined mixins for sass, which provide many neat things. Most popular ones are bourbon and susy. You can read about them by clicking on the links I provided for you. Among the others, susy is a great alternative to bootstrap grids and it will prevent your html being polluted with unsemantic classes like col-md-4. You definitely should check them out.

Reimplementing demo

Now let me give you a full reimplementation of our kitties using sass, you can skim through code on codepen, it is very simple. Try to reveal all the new concepts we've covered here in the code for this demo.

See the Pen JopZRj by Andrei Glingeanu (@andreiglingeanu) on CodePen.


Conclusion

As a conclusion, all the preprocessors and sass specifically gives us a more flexible way to structure our styles, in comparison to pure css. Now all the nesting from HTML is expressed very naturally in our stylesheets. We also don't repeat ourselves by writing colors and scalar values, which is highly error prone and is very easily to commit a mistake by using sass variables. The ability to group multiple rules under one named mixin is also a beautiful and readable way of structuring css.

These little explanations should really get you started on using sass. If you really want more you can go ahead and read official guide for this preprocessor. You may find useful documentation, which gives many more ideas and insights on using and integrating sass on different platforms and development stacks.


Wednesday, February 18, 2015

4 tips for a smarter CSS workflow

CSS workflow
Creating fancy CSS effects is great, says Shopify's Jonathan Snook, but it's more important to craft code that's fast and efficient.

You've only got to look at the amazing things people are making with CSS to know that, as a language, it's changing. People are creating stunning animations, and amazing images.

Whether you've been coding for years or just getting started, the landscape for CSS development has changed dramatically in the last few years too. Now, we have plenty of tools at our disposal that can help us to build lean, performant CSS.

Here Shopify's Jonathan Snook gives four top tips that will help you craft light-weight and fast CSS.

01. Identify unused code

Over time, projects change and your CSS may not have gotten with the times. Unused CSS impacts performance by sending needless code to the browser and making the browser work harder to identify what styles should be applied.

UnCSS will take a list of files and URLs, checks that each CSS rule is found in the HTML, and then spits out a CSS file that only includes the rules that are being used.

UnCSS requires compiled HTML & CSS and therefore may not be as helpful depending on your dev environment.

02. Identify duplicate code

As you build out a site, you'll set your sights on individual chunks of the design. When all is said and done, you may not have realized that many of the styles for the modal dialog were actually very similar to the styles for the drop-downs.

Using csscss, a redundancy checker, will help identify duplicate properties across all of your CSS rules. You can then consolidate your code into a single CSS rule.

03. Identify poor code

You've removed unused and duplicated code. What other improvements can we make to our CSS? Parker and analyze-css are two tools that analyze your stylesheets and provide metrics on the quality of your code.

Both Parker and analyze-css can help unearth parts of your code that you can simplify and refactor. Run these tools on a regular basis to help keep your CSS in check.

04. Write better code

Getting rid of bad code is one thing but writing good code to begin with is even better. Recently, a couple of guidelines have been written to help guide you to better code: CSS Guidelines and Sass Guidelines. Tooting my own horn, you should also check out SMACSS for ideas on how to write lean modular code for your project.