Ask DN: What are your little SASS/LESS time savers?

almost 7 years ago from , Head of Design at Amino

Sometimes I use web fonts with more than just normal and bold weights. It can be tricky to remember all the CSS font-weight values between 100 and 900. 400 means "normal", right? (Yes.)

I find these SASS variables helpful:

$hairline-weight: 100; $thin-weight: 200; $light-weight: 300; $normal-weight: 400; $medium-weight: 500; $semibold-weight: 600; $bold-weight: 700; $xbold-weight: 800; $black-weight: 900;

Here's a Gist with some handy synonyms and a few usage examples.

This font-smoothing mixin by Maximilian Hoffmann is another good one (to be used judiciously, of course).

Got any helpful tips?

P.S. First post—hi, everyone!


  • Jonathan SuhJonathan Suh, over 6 years ago (edited over 6 years ago )

    Sass maps and loops come in extremely handy for me.

    $social-colors: ( dribbble: #ea4c89, facebook: #3b5998, github: #171515, google: #db4437, twitter: #55acee ); @each $social-network, $social-color in $social-colors { .social-link--#{$social-network} { background: $social-color; } .social-link--#{$social-network}:hover { background: lighten($social-color, 10%); } }

    Also z-index organization:

    $z-index: ( modal : 200, navigation : 100, footer : 90, triangle : 60, navigation-rainbow : 50, share-type : 41, share : 40, ); @function z-index($key) { @return map-get($z-index, $key); } @mixin z-index($key) { z-index: z-index($key); } .navigation { @include z-index(navigation); } .modal { @include z-index(modal); }

    I wrote posts about both: Sass Maps and Organizing z-index with Sass

    21 points
    • Phil LaPierPhil LaPier, over 6 years ago (edited over 6 years ago )

      z-indices higher than 10 are a code smell to me. I've found that starting at 0 and incrementing by values of 1 helps keep z-indices much more manageable, and it's easier to understand the relationship the elements have with each other. Rarely do I use anything higher than 3 or 4.

      3 points
      • Ian WilliamsIan Williams, over 6 years ago

        +1 Try using position:relative as well.

        0 points
      • Ivan PrignanoIvan Prignano, over 6 years ago

        Abusing z-indexes is a code smell indeed, but I don't see your point – if you switch the numbers in the mixin above with incremental integers you get the same result. He just uses multiples of 10 because he wants to.

        0 points
        • Phil LaPierPhil LaPier, over 6 years ago (edited over 6 years ago )

          To clarify my point, I think the mixin is unnecessary. If you architect your CSS correctly, you won't need z-indexes higher than 3 or 4.

          Incrementing by multiples of 10 leaves room for another developer (or you) to incorrectly add index values between the ranges—e.g. [11, 12..19].

          Because z-indices can only be integers, incrementing by ones inherently preserves the single digit incrementing convention.

          1 point
          • Jonathan SuhJonathan Suh, over 6 years ago

            Ah, well the reasoning for the map and mixin is to have all of the project's z-index values in one location so before another developer adds a z-index value, he/she would add another key/value pair to the map. That way it's easy to reference the z-index values and multiple developers wouldn't lose track of them.

            2 points
      • Jonathan SuhJonathan Suh, over 6 years ago (edited over 6 years ago )

        Leaving room in between them allows me to put any additional ones in later on during the development of the project without having to adjust each and every one if one changes. And since I want to allow room in between them, I prefer to increment them by 10's, personal preference.

        I set all of my z-index values with that one Sass map so I'd have to argue the fact that it's "code smell." Having them in values of 1 or 10 shouldn't make a difference, as long as the code is well organized.

        0 points
    • Account deleted over 6 years ago (edited over 6 years ago )

      +1 for loops. Every time I run into a series of things, I end up throwing it into a loop.

      li { $colors: $primary $secondary $tertiary $quaternary; @each $color in $colors { &:nth-child(#{index($colors,$color)}) { background: $color; } } }
      0 points
  • Nick TassoneNick Tassone, almost 7 years ago

    I love using the loop functionality to generate a bunch of different classes. Here's one I've used for buttons: https://gist.github.com/ntassone/9238396

    6 points
  • Jeff ShinJeff Shin, over 6 years ago (edited over 6 years ago )

    A retina mixin is handy, especially if you want to load @2x sprites or something. Uses the @content feature of SASS.


    5 points
  • Jeff EscalanteJeff Escalante, over 6 years ago

    I save a lot of time by using stylus ; )

    4 points
  • Daniel EdenDaniel Eden, over 6 years ago (edited over 6 years ago )

    I have a few go-tos, most of which are included in every project I start.

    1. A mixin to add an SVG background image with PNG fallback.
    2. Toast has a bunch of tricks in use, including loops and placeholders.
    3. A crazy extension for Toast (not included in the actual release) to help debug grids. It basically generates gradient backgrounds to overlay columns. It's pretty gnarly. Lets me do stuff like this
    4. Some font and baseline sizing variables, based on the idea that 16px is the default font size for all browsers.

    Those are the common ones. Most of my tricks are pretty hacky.

    3 points
  • Matt HallidayMatt Halliday, over 6 years ago

    I found this article really helpful for managing color palettes and font stacks.

    3 points
  • Hugi HlynssonHugi Hlynsson, over 6 years ago (edited over 6 years ago )

    The less mixin I use most frequently is probably this float clearing technique:

    .after-clear() { &::after { content: "."; visibility: hidden; display: block; height: 0; clear: both; } }

    As for vendor prefixes, I highly recommending skipping them altogether in your code and relying on autoprefixer, which I mostly use with gulp. It saves time and keeps the code much cleaner!

    2 points
  • Suleiman Leadbitter, over 6 years ago

    P.S. First post—hi, everyone!

    Hi :)

    Great first post, I'm jacking a few of these to add into my workflow. Thanks.

    1 point
  • Patrik GothePatrik Gothe, over 6 years ago (edited over 6 years ago )

    Does stylus count? ;)

    This just my vendor prefix-method.

    v(prop, args) -webkit-{prop} args -moz-{prop} args -o-{prop} args {prop} args


    .class v(border-radius, 2px)

    This generates a random color on compilation. I use it to keep things more cheerful when developing or debugging.

    randomColor() colors = green blue orange red yellow purple index = 0 index += 1 for n in colors return colors[math(math(0, 'random')*(index), 'floor')]


    h1 color: randomColor()

    1 point
  • Callum StrongCallum Strong, over 6 years ago (edited over 6 years ago )

    REM font-sizing with pixel fallback:


    1 point
  • Wes OudshoornWes Oudshoorn, over 6 years ago

    I am saving a lot of time by using the Sass syntax instead of SCSS.

    No more semi-colons, no more brackets.

    0 points
  • Jodi WarrenJodi Warren, almost 7 years ago (edited almost 7 years ago )

    Writing this made me feel fairly smart.

    So set up your breakpoints in a SASS map

    $resolutions: ( 'phone': 480px, 'tablet': 768px, 'desktop-sm': 960px, 'desktop-lg': 1224px );

    and then automatic, easy breakpoints:

    body { @each $resolution, $size in $resolutions { @include breakpoint($size){ width: $size; } } }

    And easy media queries:

    @mixin media($type){ @if map-has-key($resolutions, $type) { $this-resolution: map-get($resolutions, $type); @include breakpoint($this-resolution) { @content; } } }

    use it like so:

    @include media('tablet'){ font-size: 12px; }

    edit: for others battling with Markdown, you need to indent code blocks with four spaces, and not surround in backticks.

    0 points
  • Matthew KosloskiMatthew Kosloski, over 6 years ago

    Wouldn't typing the desirable number for font-weight be much easier? I only use SASS for mixins, variables, and @includes.

    0 points
    • Sumul Shah, over 6 years ago

      Fewer keystrokes per declaration, yeah. But easier? Maybe, but not for me. See my reply to Daniel above.

      0 points
  • Adham DannawayAdham Dannaway, over 6 years ago

    @import "compass/css3"

    Definitely recommend using Compass with SASS http://compass-style.org/

    0 points
  • Daniel FischerDaniel Fischer, over 6 years ago

    Why would you use variables for something that is easier to type with numbers? That's the wrong way to use variables imo. Just memorize 1-9 from hairline to black.

    Better would be:

    $color-black: #333; $color-blue: #ff0044; //troll $color-primary: $color-black; $color-secondary: $color-blue;

    That way it's dynamic all the way down. Don't use variables for something that is constant and can be typed with less.

    0 points
    • , over 6 years ago

      Good question. I do use variables for colors too.

      When I'm implementing a design or coming up with new styles, I like to just type $medium-weight when I want the medium weight. It's less friction than having to remember whether I assigned medium to 500 or 600.

      It's especially helpful if I don't have all nine weights assigned and don't want to remember which ones I explicitly assigned using @font-face.

      It's also a little more maintainable. If you swap out your typeface with one that uses slightly different weights, you might want to shift things around in your @font-face declarations but not necessarily go through all your CSS replacing every 300 with a 200. You just keep it as $light-weight everywhere and make the adjustments in your _fonts.scss partial.

      I respectfully disagree that it's the wrong way to use variables. :-)

      0 points
  • Brian StudwellBrian Studwell, over 6 years ago (edited over 6 years ago )

    Nice first post!

    In a few recent projects I've found Sass super helpful for managing colors, fonts and element states.

    I work primarily in code and design in the browser, but I still find I need to see the output of a design choice to decide if it was right or not. Put another way, I like to tinker and I need to see each thing I messed with output. As such I like storing my color palette and fonts in variables so I can quickly change them and see the result.

    On a recent project I copied a few principals from this Sass style guide framework. I took my colors from the company in question's branding guidelines, converted to hex values. This gave me:

    $alpha: #262625; //charcoal gray $bravo: #852019; //crimson red $charlie: #D03226; //bright red $delta: #FFF; //pure white $echo: #E1DED2; //beige

    Then to offer me some flexibility for element states and secondary or tertiary accents, I used some Sass color functions. For instance:

    $alpha_light10:scale-color($alpha,$lightness:10%); $alpha_light20:scale-color($alpha,$lightness:20%); $alpha_light30:scale-color($alpha,$lightness:30%); $alpha_light40:scale-color($alpha,$lightness:40%); $alpha_light50:scale-color($alpha,$lightness:50%); $alpha_light60:scale-color($alpha,$lightness:60%); $alpha_light70:scale-color($alpha,$lightness:70%); $alpha_light80:scale-color($alpha,$lightness:80%); $alpha_light90:scale-color($alpha,$lightness:90%);

    This allows me (or you!) to take a particular element in the view and check out lots of different colors super fast. And you can make the color variations much more specific, I just went with 10% increments for sake of ease. As an example, let's say you have an element who's background is blue and you have assigned your brand's blue to the variable $alpha

    section.example{ background: $alpha; }

    But wait... that blue is a little much for this context. Maybe I'd like to lighten that blue up a bit--make the transition from royal to robin's egg. Let's try:

    section.example{ background: $alpha_light50; }

    Boom. Easy. Tab out to my browser. Reload the page and OH it's too MUCH! All washed out and bullshit. Welp, good thing I've set the color variants to a variable and I don't have to go find a new blue I like, then step over to a converter, find the hex value, and make sure I copy and paste it exactly in this specific context. I 'll just step over here and:

    section.example{ background: $alpha_light20; }

    Mmm. Much better. That was nice.

    0 points
  • Bart Claeys, over 6 years ago

    Not using SASS or LESS is my biggest time saver. In my opinion - and many will not agree - setting up SASS or LESS is cumbersome and the learning curve is pretty high.

    0 points
    • Alex TebbsAlex Tebbs, over 6 years ago

      Curious as to why you feel there is a high learning curve? CSS is valid SCSS or LESS. There isn't a new syntax you need to immediately learn, you can just refactor as you go. There's no need to have a full understanding of the language before you start using it. And once you do, it will save you time.

      3 points
    • Brian StudwellBrian Studwell, over 6 years ago

      I agree with Alex. There isn't much of a downside. If you're learning CSS, you're learning Sass, and if you can pick up a few Sass tricks here and there I think you might find it saves you effort and repetition down the road. Can't say the same for LESS, as I haven't used it as much, but after only a few months of experimenting with Sass, the ability to create variables for css properties like size and color attributes allows me not just to code faster, but to tinker with visual aspects of a design at a rapid pace. I would strongly recommend giving Sass another shot. Also, you don't capitalize the whole word of Sass.

      1 point
    • Namanyay GoelNamanyay Goel, over 6 years ago (edited over 6 years ago )

      Setting up: Using Prepros/Codekit etc are pretty easy for everyone, and someone with basic CL experience should find Gulp or Grunt easy to use and install.

      Learning Curve: I started off using SCSS for it's variables, and moved to Stylus and tinker with mixins a lot. There's no learning curve there, all CSS is valid SCSS/LESS/Stylus code, and using basic features increases speed and productivity (Storing font sizes, families; colors, etc).

      1 point
  • Nick PfistererNick Pfisterer, over 6 years ago (edited over 6 years ago )

    I use this one a lot to easily convert px values to rem, em or unitless (for line height).

    @function convert-px($size-px, $unit) { $output: $size-px / 16px; @if $unit == rem { @return #{$output}rem; } @if $unit == em { @return #{$output}em; } @if $unit == none { @return $output; } } // This... body { font-size: convert-px(16px, rem); line-height: convert-px(24px, none); } // ...compiles to this body { font-size: 1rem; line-height: 1.5; }

    0 points
  • Art VandelayArt Vandelay, over 6 years ago

    Be careful with the font smoothing stuff. It basically just cuts the amount of pixels on the characters in half. This article was helpful for me in learning this

    0 points
  • Scott OgleScott Ogle, over 6 years ago (edited over 6 years ago )

    This lets me really easily create linear gradients:

    @mixin linear-gradient($from, $to, $direction) { background: $to; @if $direction == vertical { background: -moz-linear-gradient(top, $from 0%, $to 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,$from), color-stop(100%,$to)); background: -webkit-linear-gradient(top, $from 0%,$to 100%); background: -o-linear-gradient(top, $from 0%,$to 100%); background: -ms-linear-gradient(top, $from 0%,$to 100%); background: linear-gradient(to bottom, $from 0%,$to 100%); } @if $direction == horizontal { background: -moz-linear-gradient(left, $from 0%, $to 100%); background: -webkit-gradient(linear, top left, top right, color-stop(0%,$from), color-stop(100%,$to)); background: -webkit-linear-gradient(left, $from 0%,$to 100%); background: -o-linear-gradient(left, $from 0%,$to 100%); background: -ms-linear-gradient(left, $from 0%,$to 100%); background: linear-gradient(to right, $from 0%,$to 100%); } }

    And this makes breakpoint-specific stuff really easy:

    @mixin breakpoint($breakpoint) { @if $breakpoint == desktop { @media screen and (min-width: 960px) { @content; } } @if $breakpoint == small-tablet { @media screen and (min-width: 640px) and (max-width: 960px) { @content; } @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (-webkit-min-device-pixel-ratio: 1){ @content; } } @if $breakpoint == phone { // This should target all phones, including iphones @media screen and (max-width: 640px) { @content; } @media only screen and (max-device-width: 320px) and (-webkit-min-device-pixel-ratio: 2) { @content; } } @if $breakpoint == iphone { @media only screen and (max-device-width: 320px) and (-webkit-min-device-pixel-ratio: 2) { @content; } } @if $breakpoint == retina { @media screen and (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @content; } } }

    with this, I can add breakpoint-specific rules like:

    @include breakpoint(phone) { display: none; }

    0 points
    • Ivan DrinchevIvan Drinchev, over 6 years ago

      Looks really similar to compass. I was wondering is there a specific benefit that you gain when using your own linear-gradient mixin instead of compass' one ?

      1 point
      • Scott OgleScott Ogle, over 6 years ago (edited over 6 years ago )

        If I was using a sufficiently large percentage of what compass offered I would probably use the whole library but for my purposes it seemed like unnecessary bloat and complexity that could be avoided by writing a few of my own mixins.

        I haven't looked at compass in some time though, so there may well be a more compelling reason for me to use it now :)

        0 points
    • Mattan IngramMattan Ingram, over 6 years ago

      If you use Autoprefixer you won't have to deal with all those annoying browser prefixes. Just write it standard and it figures out the rest for you.

      1 point
  • Ivan DrinchevIvan Drinchev, over 6 years ago (edited over 6 years ago )

    I found this one very helpful :

    @mixin position($position, $places) { @each $place in $places { #{$place}: 0; } position: $position; } @mixin size($width, $height) { width: $width; height: $height; }

    and so when you have an element that you want absolute positioned you will only write :

    .modal--close-btn { @include position(absolute, top right); @include size(55px, 55px); }

    And you will have rendered :

    .modal--close-btn { top: 0; right: 0; position: absolute; width: 55px; height: 55px; }
    0 points