Stylus styleguide - BlickLabs/generator-frontend-blick GitHub Wiki

Stylus styleguide

Braces, colons and semicolons

Altough stylus has its own syntax, which is a bit different from the pure css one, you can still write your code as if you were using css and even mix both syntaxes. However, in order to avoid potencial errors whith the stylus compiler, and to make your code easier to mantain, you have to choose between the stylus syntax and css syntax, but never mix them.

// Do
.element
  color white
  margin-top 10px

// Do
.element {
  color: white;
  margin-top: 10px;
}

// Don't!
.element {
  color white
  margin-top 10px
}

// Don't!
.element
  color white;
  margin-top: 10px

Indentation and breaklines

If you decided to use the stylus syntax, indentation is obligatory (you will have compilation errors if you don't indent your code properly), but if you chose the css one, this is not necessary. However, to keep your code legible you have to indent it, whatever syntax you prefer to use. The prefered indentation is 2 spaces.

// Do
.element
  color white

// Don't!
.element
color white

// Do
.element {
  color: white;
}

// Don't!
.element {
color: white;
}

Additionally, add a breakline after the last declared property of a block:

// Do
.element
  color white

.other-element
  color white
// Don't!
.element
  color white
.other-element
  color white
// Do
.element
  color white

  .other-element
    color white
// Don't!
.element
  color white
  .other-element
    color white

Variables

All variables should be declared inside vars.styl file and start with the $ symbol.

Mixins

Mixins are declared with the following syntax:

mixin-name(parameter1, parameter2, ...) // Parameters are optional
  code

Once that they are declared you can use them by either parenthesis syntax or css-alike syntax.

// Parenthesis
.some-class
  mixin-name(parameter1, parameter2, ...)

// Css-alike
.some-class
  mixin-name parameter1 parameter2

There are two types of mixin, one that returns a value and the other that doesn't. The first one must be used as a css property value and with parenthesis syntax, and the second one as a css propery name.

// If mixin returns a value
.some-class
  css-property mixin-name(parameter1, parameter2, ...)

// If mixin doesn't return a value
.some-class
  mixin-name(parameter1, parameter2, ...)
  // or
  mixin-name parameter1 parameter2

Sections and media queries

Create a stylus file inside src/styl/sections/ for every nunjucks file you create in src/templates/sections/. Try to avoid media queries inside code blocks, and instead add all your media queries at the end of the file.

/* index.styl */
// DO
.element
  color white
...
...
...
@media screen and (max-width: 600px)
  .element
    color black
/* index.styl */
// You can do it, but it'd be better if you don't
.element
  color white
  
  @media screen and (max-width: 600px)
    color black

If for any reason your media queries become too long, you can write them in a different file. If you do this, you should create a third subfolder inside src/styl/ called responsive.

src/
  styl/
    partials/
    responsive/
    sections/

Then, you have to import that folder inside main.styl

@import 'vars'
@import 'mixins'
@import 'fonts'
@import 'utils'

@import 'base'

import_tree('./sections')
import_tree('./responsive')

remify & rfont-size

In order to reduce the amount of code related to responsive styles, you can (and should) either the remify() or the rfont-size() mixins included in this generator.

remify() will scale the font-size at certain breakpoints (you can see them inside base.styl) and it's useful for titles and subtitles. Note that the value that you pass to the mixin is a plain number without any unit. The calculated sizes don't usually look well in the following two cases, as they may look too small or too big:

  • If the original font-size is smaller than 17px
  • If the original font-size is bigger than 40px

For this reason, rfont-size() is a better option for paragraphs and subtitles that are smaller than 17px. The sintax for this mixin is (you can use either parenthesis or css-alike syntax):

r-font-size(baseSize, mediaSize, newSize, [useMin = false])
  • baseSize: Original font-size that is used in the design you have to adapt.
  • mediaSize: Breakpoint (screen size) from which it's necessary to change the font-size
  • newSize: Font-size to use after the breakpoint is reached
  • useMin (default: false): It specifies if your implementation is considered mobile-first or not. If true, the breakpoint will use a min-width condition. If false, max-width will be used instead.

Note that, if you consider it necessary, you can use remify() units for both baseSize and newSize parameters.

Inputs padding

Since the padding of input elements should look proportional to the text inside it, you should never use pixel based paddings (you'd need to modify them manually). Instead, use em units. This can be done by using the unit() stylus function with the following syntax (note that pixelBasedPadding and pixelBaseFontSize are plain numbers without any unit):

padding unit(pixelBasedPadding/pixelBaseFontSize, 'em')

You can also use the remify() mixin, but you have to be careful with the exceptions mentioned in the previous section.

Additionally, you can use this method with a lot of paddings and margins (but not all of them) to avoid writing lots of media queries.

Declaring custom fonts

You have to create a @font-face declaration for every font variation that you need, all of them with different attributes (inside fonts.styl). Don't use a different font-family name for each variation (they are part of the same family).

/* fonts.styl */
// Do
@font-face
  font-family 'Open Sans'
  font-style normal
  font-weight $normal
  src url('#') format('#')

@font-face
  font-family 'Open Sans'
  font-style italic
  font-weight $normal
  src url('#') format('#')

@font-face
  font-family 'Open Sans'
  font-style normal
  font-weight $bold
  src url('#') format('#')
/* fonts.styl */
// Don't!
@font-face
  font-family 'Open Sans Regular'
  font-style normal
  font-weight normal
  src url('#') format('#')

@font-face
  font-family 'Open Sans Regular italic'
  font-style normal
  font-weight normal
  src url('#') format('#')

@font-face
  font-family 'Open Sans Bold'
  font-style normal
  font-weight normal
  src url('#') format('#')

Nested styles and !important

Try not to have more than 3 levels of nested styles and avoid using !important. If you don't follow this advice, you will have problems when trying to override styles (like in media queries).

Vendor prefixes

You don't need to add vendor prefixes. The build:styles gulptask includes stylus-autoprefixer.