Bom estou escrevendo esse passo-a-passo pois me foi pedido via inbox do Facebook para que eu mostrasse como eu iria programar o site que estou desenvolvendo para um curso de Javascript que na verdade serão vários mini-cursos podendo ter outro professores.
Então achei uma boa oportunidade para colocar em prática alguns estudos e experimentar coisas novas como: Stylus e Mobile-first. Juntando tudo com Atomic Design, esse post vai ficar gigante e muito provavelmente virará um mini-curso e uma palestra também, até porque de nada vale aprender se não ensinar, imho.
##Analisando
Bom vamos ver como é o layout com o qual vamos trabalhar, vamos nos basear nele pois coisas podem ser modificadas durante o desenvolvimento.

Primeiro escrevi uma lista dos componentes e a estrutura do layout mas nada de HTML ou CSS.
header
logo[4/12]
menu[6/12]
button matricule-se medium[2/12]
main
article
title#1
video //curso com fundo notebook
title#2
p
article
title#3 Confira nossos cursos
box-curso*3
img thumb
titulo
resumo
box-ver-mais
article
p
button matricule-se
article
title#3[1/3] Aprenda diretamente com os melhores intrutores
article
title#3[1/3] Pronto para começar?
- p
img logo[1/3]
button matricule-se large[1/3]
footer
Fiz algumas marcações de tamanho baseado no container para facilitar na hora de setar o grid. Perceba que nem fiz o footer pq sou vagabundo ehehheheh.
Depois criei a listagem dos primeiros átomos em atoms/atoms-default.styl:
.atom-img
.atom-img-logo
.atom-img-logo-small
.atom-img-logo-medium
.atom-img-logo-large
.atom-img-professor-avatar
.atom-input
.atom-input-email
.atom-button
.atom-button-matricule-se
.atom-button-matricule-se-small
.atom-button-matricule-se-medium
.atom-button-matricule-se-large
.atom-title
.atom-title-primary
.atom-title-secondary
.atom-title-section
.atom-link
.atom-link-menu
.atom-text
.atom-text-cursos
.atom-text-professor-resumo
São apenas um base para iniciar, pois provavelmente adicioneremos outros dependendo da necessidade.
Mas o correto era iniciar pelos bósons que são as menores unidades que irão "dar massa" aos átomo. Levando isso em consideração iniciei setando as variáveis das cores em bosons/bosons-colors.styl.
$azul-claro = #1680a7
$azul-cinza-escuro = #202b31
$branco = #fff
$verde-claro = #6ed5a2
$azul-cinza-medio = #788c95
$color-bg-body = $branco
$color-bg-header = $azul-claro
$color-bg-main = $branco
$color-bg-cursos = $azul-cinza-escuro
$color-bg-footer = $azul-cinza-escuro
$color-bg-button = $verde-claro
$color-title-main = $branco
$color-title-secondary = $azul-claro
$color-text = $azul-cinza-medio
$color-link = $verde-claro
Para criarmos variárveis no Stylus basta definir o nome depois = e o valor, por definição usamos o $ como prefixo padrão, leia mais sobre o porquê usar $.
Nomeei as cores para ficar mais facilmente indentificáveis e facilmente subistituídas. Após as cores criei o arquivo dos bósons de tipografia em bosons/boson-typo.styl
$font-default = 'Myriad Pro, Sans serif'
$font-bold = 'normal'
$font-size-base = 62.5%
set-font-size(value) {
font-size: value; /* add PX (or original value) as backup */
if (value is inherit) {
/* do nothing, "inherit" has no unit */
} else {
font-size: remify(value);
}
}
remify(value) { /* separate mixin, so it can be used elsewhere */
u = unit(value);
if (u is 'px') {
return unit(value/16, 'rem');
} else {
return unit(value, u);
}
}
Percebam esses 2 mixins set-font-size e remify eles irão fazer o trabalho de converter as unidades de pixels para REM, então você não precisará fazer mais cálculos, esses mixins foram retirados daqui - Stylus REM.
Um exemplo do que será gerado com esse código:
.smaller {
set-font-size(13px);
}
Vira:
.smaller {
font-size: 13px;
font-size: .8125rem;
}
Outro caso interessante de se notar que como usamos REM para fazer nossas fonts diminuírem ou aumentarem dependendo da responsividade, podemos apenas setar o valor da font na tag HTML que é a root de todas e é de onde o REM deriva seu valor, como visto nesse artigo
BREAK IN
Antes de iniciarmos vamos utilizar o normalize para podermos iniciar nosso visual igual em todos navegadores. Para isso o temos o reset.styl lembrando que o Stylus eh JAVASCRIPT <3
npm install reset.styl
E para usarmos:
use_reset('normalize')
BREAK OUT
Agora vamos iniciar criando os estilos para nossos atomos, lembrando que eles precisam ser responsíveis, nosso padrão será o mobile-first. Então vamos criar as variáveis de tamanho em bosons/boson-responsive.styl
$tablet-size = 768px
$desktop-size = 1000px
Mas depois nossa responsividade será feita com o Rupture, bora instalar:
npm install rupture
##Iniciando
###Header

Vamos iniciar o desenvolvimento visual a partir dos componentes, então vamos começar pelo header que será um organismo pois agregará átomos e moléculas.
header
img.atom-logo-header( src='logo-header.png',
alt='Logo da empresa Webschool',
aria-label='Logo da empresa Webschool')
ul.molecule-menu-header
li.atom-link-menu menu 1
li.atom-link-menu menu 1
li.atom-link-menu menu 1
button.atom-matricule-se-small matricule-se
Para criarmos o atom-logo-header precisamos inicialmente criar o átomo padrão das imagens, .atom-img e posteriormente o .atom-img-logo:
// configurações básicas
// usando placeholder para
// não criar uma classe a mais
$atom-img
border-image 0
margin 0
padding 0
display inline-block
// configurações específicas do logo
.atom-logo-header
@extend $atom-img
// para não ficar sem imagem caso o href não seja passado
background-image url('../img/logo-header.png')
// tamanho fixo da imagem
// mesmo em telas maiores ele se mantém
width 244
height 103
####Placeholder
Utilizo o placeholder pois ele só gerará o código quando extendido, sem precisar criar uma classe antes para extender.
Por exemplo:
$bold
font-weight bold
.title
@extend $bold
Vai gerar:
.title{
font-weight: bold;
}
Enquanto que usando classe fica:
.bold
font-weight bold
.title
@extend $bold
Que gera:
.bold,
.title{
font-weight: bold;
}
No final das contas irá diminuir nosso código porém há um problema ainda com os pré-processadores onde você não pode re-utilizar um placeholder em uma media query que foi criado fora dela, mas para isso existem algumas alternativas.
Como a qual o Diogo Moretti fez no grider que gerou o mesmo grid para cada media query.
Esse artigo que fala do mesmo tema porém com SASS também é uma ideia interessante e mais aprimorada.
Vamos usar uma forma um pouco diferente e mais simples, ideia dada pelo Fernando Daciuk, iremos definir as medias em um mixin e re-usá-las no nosso átomo, como visto abaixo:
$atom-img
border-image: 0
margin: 0 auto
padding: 0
display: block
max-width: 100%
margin-left: 20px
margin-top: 8px
width: 80%
// tamanho padrão p/ telas acima do mobile
@media (min-width: 600px)
width: 200px
// configurações específicas do logo
atom-logo-header-medias()
@media (min-width: 600px)
width: 244px
.atom-logo-header
atom-logo-header-medias()
@extend $atom-img
width: 40%
O resultado é esse:
*adicionei um fundo pois o logo tem muito branco
Infelizmente esse código duplica nosso CSS, porém infelizmente para re-usar um código em uma media query você precisa definir ele dentro dela. Existem formas melhores de fazer isso, quando refatoraremos essa parte.
.atom-logo-header {
-webkit-border-image: 0;
-o-border-image: 0;
border-image: 0;
margin: 0 auto;
padding: 0;
display: block;
max-width: 100%;
margin-left: 20px;
margin-top: 8px;
width: 80%;
}
@media (min-width: 600px) {
.atom-logo-header,
.atom-logo-header {
width: 200px;
}
}
.atom-logo-header {
width: 40%;
}
@media (min-width: 600px) {
.atom-logo-header {
width: 244px;
}
}
####Menu
Pronto agora vamos estilizar nosso componente de menu, inicialmente estilizamos apenas os li's, pois o ul é uma molécula que irá agregar 1 ou mais átomos, podendo esses ser qualquer coisa. Ex.: link, texto, imagem, vídeo, etc.
.atom-link-menu
@extend $boson-link
text-transform: uppercase
color: $branco
Percebeu que extendemos o placeholder do boson-link? Pois ele será base para outros links assim como atom-img é para as imagens, iremos refatorar futuramente.
Ele está definido em bosons/boson-typo:
$atom-link
text-align: left
text-decoration: none
font-size: 1em
color: $verde-claro
Como estamos desevolvendo orientado a componentes vamos estilizar nossa molécula do menu para que ele se pareça com um menu mobile. Criamos o arquivo molecules/index pois ele será o único a ser importado no main, precisamos refatorar o de átomos também para que fique mais simples de gerenciar e manter.
.molecule-menu-header
list-style: none
display: inline-block
float: right
margin-right: 0.6em
Como estamos fazendo mobile-first vamos ter que criar um menu escondido e mostrar apenas aquele ícone que todos conhecem das 3 listras horizontais.
.atom-link-menu-icon
background: url('../img/icon-png2x.png') no-repeat top center
color: transparent
display: block
text-align: center
text-indent: 99999px
width: 2em
height: 2em
a
span
display: none
Nossa view poderia ficar assim:
ul.molecule-menu-header
li.atom-link-menu-icon
a(href='#')
img(src='img/icon-png2x.png', alt='Clique para abrir o menu')
li
a.atom-link-menu(href='#') menuu
li
a.atom-link-menu(href='#') menu
li
a.atom-link-menu(href='#') menu
li
a.atom-link-menu(href='#') menu

Porém ainda estamos mostrando a listagem abaixo, vamos refatorar e chegar na usabilidade já conhecida dos menus mobile.
Para isso vamos iniciar utilizando uma técnica onde criamos um checkbox invisível e adicionamos um label com o ícone do menu, quando esse label é clickado ou tocado nosso CSS irá fazer a lista do menu aparecer.
Vamos começar pela estrutura do nosso menu:
input(type="checkbox",
id="atom-menu-checkbox",
class="atom-menu-checkbox")
nav.molecule-menu
label(for="atom-menu-checkbox",
class="atom-menu-handle")
ul.molecule-menu-header
li.atom-item-menu
a.atom-link-menu(href='#') menuu
li.atom-item-menu
a.atom-link-menu(href='#') menu
li.atom-item-menu
a.atom-link-menu(href='#') menu
li.atom-item-menu
a.atom-link-menu(href='#') menu
li.atom-item-menu
button.atom-matricule-se-small matricule-se
Percebeu que o input está fora?
É para termos acesso a ele quando o menu estiver escondido. Então vamos estilizar nosso label e esconder o checkbox:
.atom-menu-handle
ba