CSS Tools for Devs

Oleksii Vasyliev, Railsware

CSS Tools for Devs

Brought to you by Alexey Vasiliev, Railsware

Oleksii Vasyliev

CSS basics

CSS basics

  • CSS selectors
  • Inheritance and the cascade
  • Box model
  • CSS Flow Layout
  • CSS Layout
  • Responsive Design
  • Fonts And Typography
  • Transforms And Animation
cat explorer
scary css

CSS architecture systems

Benefits of Thoughtful CSS Architecture

  • Scalability
  • Fewer styling rules
  • Long-term maintainability
  • Fewer styling collisions
  • Faster ramp-up
  • Easier collaboration
CSS Architecture

Object Oriented CSS (OOCSS)

In a nutshell: Divide layout into objects, then abstract their CSS into modules, more info

.button { padding: 10px 16px; }
.primary-skin { color: blue; }
.secondary-skin { color: green; }
<button class="button primary-skin">primary button</button>
<button class="button secondary-skin">secondary button</button>
<div class="primary-skin">primary skin div</div>

Scalable and Modular Architecture for CSS (SMACSS)

In a nutshell: Split CSS code across multiple files for better performance and organisation, more info

nav.nav-primary li {
  display: inline-block;
}
nav.nav-secondary li {
  display: block;
}

Inverted Triangle CSS (ITCSS)

In a nutshell: Separation of the CSS codebase into several layers, based on the specificity level, more info

@import "objects.animations";
@import "objects.drawer";
@import "objects.list-bare";

@import "components.404";
@import "components.about";
@import "components.archive";

Atomic CSS (ACSS)

In a nutshell: Create a class selector for every repeating CSS declaration, more info

<div class="Bgc(#0280ae.5) C(#fff) P(20px)">
  Lorem ipsum
</div>

Block Element Modifier (BEM)

In a nutshell: Use a standard naming convention for classes, more info

<ul class="list-block list-block--inline">
  <li class="list-block__item">Item 1</li>
  <li class="list-block__item">Item 2</li>
</ul>

Is there a best CSS architecture system?

NO

CSS Frameworks

Bootstrap

  • Release date: August 19, 2011
  • Core concept: RWD and mobile-first
  • SMACSS Architecture
  • Offers lots of examples and a pre-set layout to get you started with
getbootstrap

Foundation

  • Release date: November 4, 2014
  • Core concept: RWD and mobile-first
  • SMACSS Architecture
  • Have "Foundation for Emails 2"
Foundation

Bulma

  • Release date: January 24, 2016
  • Core concept: RWD, mobile-first, Modern free
  • SMACSS Architecture
  • Offers clean and simple presets which make it easy to choose as per the topics the developer wants to explore
bulma

UIkit

  • Release date: January 09, 2017
  • Core concept: RWD, minimalism
  • SMACSS Architecture
  • Minimalism not in features, but in design
UIkit

Tailwind CSS

  • Release date: November 2, 2017
  • Core concept: RWD and utility first
  • Utility-first CSS/ Atomic CSS Architecture
  • Operates on a lower level and offers you a set of CSS helper classes
Tailwind CSS

Tailwind CSS

<div
  class="w-16 h-16 rounded text-white
  bg-black py-1 px-2 m-1 text-sm md:w-32
  md:h-32 md:rounded-md md:text-base
  lg:w-48 lg:h-48 lg:rounded-lg lg:text-lg"
>
  Yikes.
</div>

Tailwind CSS

.c-input {
  @apply block appearance-none bg-white placeholder-gray-600
  border border-indigo-200 rounded w-full py-3 px-4
  text-gray-700 leading-5 focus:outline-none
  focus:border-indigo-400 focus:placeholder-gray-400
  focus:ring-2 focus:ring-indigo-200;
}
TailwindCSS

CSS Tools

CSS Preprocessors

  • SASS
  • LESS
  • Stylus
  • CSS-Crush
SASS

CSS Postprocessors

  • PostCSS
  • Pleeease
  • Stylecow
PostCSS

Postcss-preset-env

postcss-present-env.png

Lost grid

section {
  lost-utility: clearfix;
}

div {
  lost-column: 1/2;
}

PreCSS

$blue: #056ef0;
$column: 200px;

.menu {
  width: calc(4 * $column);
}

.menu_link {
  background: $blue;
  width: $column;
}

SugarSS

a
  color: blue

.multiline,
.selector
  box-shadow: 1px 0 9px rgba(0, 0, 0, .4),
              1px 0 3px rgba(0, 0, 0, .6)

Rucksack

.foo {
  font-size: responsive;
}

.foo {
  color: rgba(#fff, 0.8);
}

CSSNano

cssnano

PurgeCSS

purgecss

CSS MQPacker


.foo {
	width: 240px;
}

.bar {
	width: 160px;
}

@media screen and (min-width: 768px) {
	.foo {
		width: 576px;
	}
	.bar {
		width: 384px;
	}
}
        

CSS-in-JS (Second generation)

CSS-in-JS (3rd generation)

more info

Stylelint

stylelint
linters

Stylelint plugins

Testing

storybook
StorybookFlow

Unit tests

import React from 'react'
import {render, screen} from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'

//👇 Imports a specific story for the test
import {Primary} from './Button.stories'

it('renders the button in the primary state', () => {
  render(<Primary {...Primary.args} />);
  expect(screen.getByRole('button')).toHaveTextContent('Primary Button');
});

Visual Testing with Storybook

component-visual-testing

Visual Testing with Storybook

import initStoryshots from '@storybook/addon-storyshots'
import {imageSnapshot} from '@storybook/addon-storyshots-puppeteer'

initStoryshots({
  suite: 'Basic storyshots',
  test: imageSnapshot({storybookUrl: 'http://localhost:6006/'})
})

Pixelmatch vs SSIM

TestingVisualSSIM
TestingVisualExample1
TestingVisualExample2
TestingVisualExample3

Visual Testing with Storybook

describe('<Button />', () => {
  ...
  it('check content after clicking', async () => {
    // navigate to story
    await page.goto(
      'http://localhost:6006/iframe.html?id=components-button--primary',
    )
    // click on the button
    await page.click('button')
    // take screenshot and compare
    const screenshot = await page.screenshot()
    expect(screenshot).toMatchImageSnapshot() // import {toMatchImageSnapshot} from 'jest-image-snapshot'
  })
})

Conclusion

Guideline for Dev Teams

<Thank You!> Questions?

Contact information

QuestionsSlide