Rompendo os (vários) Limites do CSS com Sass e Compass

Preview:

DESCRIPTION

Slides do meu workshop sobre Sass + Compass.

Citation preview

SassROMPENDO OS (VÁRIOS) LIMITES DO CSS COM

+ Compass

ALCIDES QUEIROZ

+ Compass

ALCIDES QUEIROZ

ROMPENDO OS (VÁRIOS) LIMITES DO CSS COM

+

ALCIDES QUEIROZ

ROMPENDO OS (VÁRIOS) LIMITES DO CSS COM

+

ALCIDES QUEIROZ

/alcidesqueiroz

/alcidesqueiroz

/alcidesqueiroz

goo.gl/0HSUA4

ROMPENDO OS (VÁRIOS) LIMITES DO CSS COM

ALCIDES QUEIROZ

Just install it:

goo.gl/48fowWROMPENDO OS (VÁRIOS) LIMITES DO CSS COM

O PROBLEMA

OS PROBLEMAS

OS PROBLEMAS

ORGANIZAÇÃO

REUSO

COMPLETAMENTE LOGICLESS

VERBOSO

IMPORTS PROBLEMÁTICOS

SASS

O que é?

Pré-processador CSS criado em 2007 por Hampton

Catlin

SASS E SCSS

Sintaxe identada

#main

color: blue

font-size: 0.3em

a

font:

weight: bold

family: serif

&:hover

background-color: #EEE

COMPILANDO

sass --update .

sass --update --no-cache .

sass --update --no-cache .:..\\CSS

sass --watch --no-cache .:..\\CSS

sass --watch --no-cache --poll .:..\\CSS

COMENTÁRIOS

//Comentário inline

/*

Comentário

Em

Bloco

*/

ANINHAMENTO DE SELETORES

CSS

body {

background-color: #FF0;

}

body > header {

width: 900px;

}

body > header h1 {

font-weight: normal;

}

ANINHAMENTO DE SELETORES

SCSS

body {

background-color: #FF0;

> header{

width: 900px;

h1{

font-weight: normal;

}

}

}

ANINHAMENTO DE SELETORES

SCSS

body, #wrapper {

background-color: #FF0;

> header{

width: 900px;

h1{

font-weight: normal;

}

}

}

ANINHAMENTO DE SELETORES

CSS Gerado

body, #wrapper {

background-color: #FF0;

}

body > header, #wrapper > header {

width: 900px;

}

body > header h1, #wrapper > header h1 {

font-weight: normal;

}

NÃO ABUSE!

SIGA A REGRA DOS 4 NÍVEIS

(&) REFERENCE SELECTOR

h1, h2 {

&:before{

margin-right: 10px;

}

.standout {

color: red;

}

&.title{

font-weight: bold;

}

}

(&) REFERENCE SELECTOR

h1:before, h2:before {

margin-right: 10px;

}

h1 .standout, h2 .standout {

color: red;

}

h1.title, h2.title {

font-weight: bold;

}

CSS Gerado

LET’S CODE!

VARIÁVEIS

$base-color: #679;

color: $base-color;

$default-border-radius: 3px;

border-radius: $default-border-radius;

VARIÁVEIS - A FLAG !default

$base-color: #679;

$base-color: #444;

Agora, o valor de $base-color é #444

VARIÁVEIS - A FLAG !default

$base-color: #679;

$base-color: #444 !default;

O valor de $base-color é #679

VARIÁVEIS - OUTROS USOS

SELETORES

$button-icon-selector: “.btn button .icon:before”;

VARIÁVEIS - OUTROS USOS

PROPRIEDADES COMPLEXAS

$default-border: dotted 2px #444;

$strange-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75),

-10px 5px 20px #444;

VARIÁVEIS - OUTROS USOS

EM CONJUNTO COM OUTRAS VARIÁVEIS

$default-border-style: dotted;

$default-border-color: #222;

$default-border-width: 2px;

$default-border: $default-border-style

$default-border-color $default-border-width;

VARIÁVEIS - OUTROS USOS

ETC...

$default-transition-duration: 300ms;

$mask-opacity: 0.7;

$default-label-separator: ‘:’;

LET’S CODE!

INTERPOLAÇÃO

$side: left;

$border: "solid 1px #000";

.nome-de-classe-#{$side}{

text-align: $side;

float: #{$side};

border-#{$side}-width: 1px;

border-top: $border;

border-right: #{$border};

}

INTERPOLAÇÃO

.nome-de-classe-left {

text-align: left;

float: left;

border-left-width: 1px;

border-top: "solid 1px #000"; /*ops...*/

border-right: solid 1px #000;

}

CSS Gerado

IMPORTANDO

@import ‘variables’;

IMPORTANDO - CSS VS SCSS

//Os 4 imports abaixo são imports convencionais do CSS

@import "main.css";

@import "boleto" print;

@import "http://teste.com/layout.css";

@import url("font-face.css");

/* O import abaixo não possui extensão CSS, nem é

definido via url(), não inicia com "http://" ou possui

uma media query, portanto o Sass tentará localizar um

arquivo .SCSS ou .SASS equivalente*/

@import ‘variables’;

IMPORTANDO - @import ANINHADO

Exemplo.scss

.top-bar{

.user{

color: #000;

}

}

Exemplo2.scss

#main{

@import ‘exemplo’;

}

IMPORTANDO - @import ANINHADO

#main .top-bar .user {

color: #000;

}

CSS Gerado

PARTIALS

_variables.scss

ORGANIZANDO

variáveis

mixins

componentes

dependências do compass

font-face

layout

ANINHAMENTO DE PROPRIEDADES

CSS

.profile{

border-left: solid 1px #000;

border-right: dotted 4px #FF0;

}

ANINHAMENTO DE PROPRIEDADES

SCSS

.profile{

border:{

left: solid 1px #000;

right: dotted 4px #FF0;

}

}

ANINHAMENTO DE PROPRIEDADES

SCSS

.profile{

border: dashed 2px #00F {

left: solid 1px #000;

right: dotted 4px #FF0;

}

}

LET’S CODE!

Sass INTERACTIVE

sass -i

DIRETIVA @debug$largura-padrao: 260px;

$largura-total: $largura-padrao * 2;

@debug "Largura total: #{$largura-total}";

TIPOS DE DADO

números

2.5, 20, 40px, 50deg, 600ms

strings

sans-serif, “exemplo”, ‘h1+h2’

cores

black, #ABCDEF, rgba(0, 0, 100, 1)

booleans

true e false

Strings são sempre traduzidas

de forma literal, a não ser em

interpolações, onde strings

“quoted” perdem suas aspas.

TIPOS DE DADO

nulls

null

listas (listas de valores separados por espaço ou vírgula)

10px 10px 15px 10px

double 5px #FDD;

"Lucida Grande", Tahoma, Verdana, Arial, sans-serif

10px 12px, 20px 40px

Uma lista de listas... =)

(10px 12px), (20px 40px)igual a

A flag !default considera variáveis null

como não-definidas, e as reescreve

OPERADORES MATEMÁTICOS

+ soma

- subtração

* multiplicação

/ divisão

OPERADORES MATEMÁTICOS

$altura: 50px * 3 + 400px;

$angulo: 30deg * 4;

$duracao: 400ms * 5;

$largura: ($tamanho-padrao * $quantidade) +

($espacamento-padrao * ($quantidade – 1)) +

($espacamento-padrao / 2);

OPERADORES MATEMÁTICOS

O curioso caso do operador /

font: 20pt/40pt; /*Isso não é uma

divisão*/

width: 50px/2; //Isso também não...

width: (50px/2); /*Isso SIM é uma

divisão*/

$largura: 50px/2; //Isso também

width: 50px/2+1; //E isso...

OPERADORES DE COMPARAÇÃO

> maior que

< menor que

>= maior ou igual que

<= menor que ou igual

== igual a

!= diferente de

OPERADORES DE COMPARAÇÃO

$exemplo: 10 > 6 and (4 > 5 or 3 == 3);

$exemplo2: 20 != 30;

$exemplo3: $b >= 18;

OPERADORES LÓGICOS

not

and

or

OPERADORES LÓGICOS

$exemplo: (true and false) or true;

$exemplo2: not $habilitar-animacoes;

DIRETIVAS DE CONTROLE @if, @else,

@else if

$inverse-color: true;

.introduction{

background-color: $base-color;

@if $inverse-color{

color: #FFF;

}

}

DIRETIVAS DE CONTROLE @if, @else,

@else if

@if $width == 'auto' {

//…

} @else if $width == 1 {

//…

} @else {

display: inline-block;

width: $width;

}

DIRETIVAS DE CONTROLE @if, @else,

@else if

@if $auto-resize and $largura > 300px{

//…

} @else if not $auto-resize {

//…

} @else {

//…

}

DIRETIVA DE CONTROLE @for

@for $i from 1 through 4 {

.nivel-#{$i} {

font-size: 20px + (12px / $i);

}

}

.nivel-1 { font-size: 32px; }

.nivel-2 { font-size: 26px; }

.nivel-3 { font-size: 24px; }

.nivel-4 { font-size: 23px; }

DIRETIVA DE CONTROLE @for

@for $i from 1 through 4 {

.nivel-#{$i} {

font-size: 20px + (12px / $i);

}

}

.nivel-1 { font-size: 32px; }

.nivel-2 { font-size: 26px; }

.nivel-3 { font-size: 24px; }

.nivel-4 { font-size: 23px; }

DIRETIVA DE CONTROLE @for

@for $i from 1 to 4 {

.nivel-#{$i} {

font-size: 20px + (12px / $i);

}

}

.nivel-1 { font-size: 32px; }

.nivel-2 { font-size: 26px; }

.nivel-3 { font-size: 24px; }

DIRETIVA DE CONTROLE @while

$i: 1;

@while $i <= 5 {

.nivel-#{$i} { text-indent: 1cm * $i; }

$i: $i + 1;

}

.nivel-1 { text-indent: 1cm; }

.nivel-2 { text-indent: 2cm; }

.nivel-3 { text-indent: 3cm; }

.nivel-4 { text-indent: 4cm; }

.nivel-5 { text-indent: 5cm; }

DIRETIVA DE CONTROLE @each

@each $carro in chevette, opala, kadett {

.detalhes-#{$carro} {

background-image: url('/images/#{$carro}.png');

}

}

.detalhes-chevette{ background-image: url("/image/chevette.png");}

.detalhes-opala{ background-image: url("/image/opala.png");}

.detalhes-kadett{ background-image: url("/image/kadett.png");}

DIRETIVA DE CONTROLE @each

div{

$i: 2px;

@each $lado in top, right, left, bottom {

border-#{$lado}-width: $i;

$i:$i+2px

}

}

div {

border-top-width: 2px;

border-right-width: 4px;

border-left-width: 6px;

border-bottom-width: 8px;

}

OPERAÇÕES COM CORES

red + blue //=>#FF00FF

#234 * 3 //=>#6699CC

#DDD - #FF0 //=>#0000DD

#FFF / 10 //=> #191919

LET’S CODE!

HERANÇA - TENTATIVA 1

.profile{

border: solid 2px #222;

overflow: hidden;

color: #D22;

display: inline-block;

background-color: #FFF;

}

CSS

.corporative-profile{

border: solid 2px #222;

overflow: hidden;

color: #D22;

display: inline-block;

background-color: #DD2;

}

HERANÇA - TENTATIVA 1

Problemas desta abordagem:

Não é DRY

Manutenibilidade

HERANÇA - TENTATIVA 2

.profile,

.corporative-profile {

border: solid 2px #222;

overflow: hidden;

color: #D22;

display: inline-block;

background-color: #FFF;

}

CSS

.corporative-profile {

background-color: #DD2;

}

HERANÇA - TENTATIVA 2

Problemas desta abordagem:

Manutenibilidade: para caçar de quem um

determinado seletor herda

Manutenibilidade - parte 2: Os seletores filhos poluem

o seletor da regra base:

.profile,.corporate-profile,.student-profile,

.consultant-profile,etc.

HERANÇA - TENTATIVA 3

.profile{

border: solid 2px #222;

overflow: hidden;

color: #D22;

display: inline-block;

background-color: #FFF;

}

.corporative-profile{

background-color: #DD2;

}

CSS + HTML

<div class=“profile

corporative-profile”>…</div>

HERANÇA - TENTATIVA 3

Problemas desta abordagem:

Não há clara relação de extensão no código CSS

Dificulta múltiplos níveis de herança

Uma certa transferência de lógica de

estilização para o HTML

HERANÇA - THE SASS WAY!!!

.profile{

border: solid 2px #222;

overflow: hidden;

color: #D22;

display: inline-block;

background-color: #FFF;

}

SCSS

.corporative-profile{

@extend .profile;

background-color: #DD2;

}

HERANÇA

.profile, .corporative-profile {

border: solid 2px #222;

overflow: hidden;

color: #D22;

display: inline-block;

background-color: #FFF;

}

.corporative-profile {

background-color: #DD2;

}

CSS Gerado

WTF?

Um deja vu!?!?

HERANÇA - DEJA VU...

• Sim, o código gerado é igual ao da

tentativa 2.

• O único e grande problema da técnica

adotada era manutenibilidade

• Porém... você não precisa e nem deve manter o seu CSS gerado

• Preocupe-se apenas em manter um SCSS limpo,

manutenível, modularizado e fazer uso inteligente e

sensato dos seus seletores. Deixe a compilação com o Sass e descanse.

HERANÇA MÚLTIPLA

.detalhes{

border: dashed 3px #000;

}

.tile{

background-color: #2D2;

}

SCSS

.ficha{

@extend .detalhes;

@extend .tile;

color: #FFF;

}

HERANÇA MÚLTIPLA

.ficha{

@extend .detalhes, .tile;

color: #FFF;

}

Ou assim...

HERANÇA - ALÉM DE CLASSES

h1{

font-weight: normal;

font-family: OpenSans

Regular;

font-size: 30px;

}

#titulo{

text-transform: uppercase;

color: #222;

}

SCSS

h2{

@extend h1,

#titulo;

font-size: 20px;

}

HERANÇA - ALÉM DE CLASSES

h1, h2 {

font-weight: normal;

font-family: OpenSans Regular;

font-size: 30px;

}

#titulo, h2 {

text-transform: uppercase;

color: #222;

}

h2 {

font-size: 20px;

}

CSS Gerado

HERANÇA - SELETORES ANINHADOS

button{

&.general-button{

border-radius: 3px;

background-color: #22D;

}

}

.general-button{

color: #FFF;

}

SCSS

.dangerous-button{

@extend .general-button;

background-color: #D22;

}

HERANÇA - HERDANDO DO “NADA”

button{

@extend .essa-classe-nao-existe;

}

SCSS

<< Kaboom!

HERANÇA - A FLAG !OPTIONAL

button{

@extend .essa-classe-nao-existe !optional;

}

SCSS

HERANÇA - SELETORES ABSTRATOS

%teste{

color: blue;

}

.teste2{

@extend %teste;

font-weight:

normal;

}

.teste3{

@extend %teste;

font-weight: bold;

}

SCSS.teste{

color: blue;

}

.teste2{

@extend .teste;

font-weight:

normal;

}

.teste3{

@extend .teste;

font-weight: bold;

}

VS.

HERANÇA - SELETORES ABSTRATOS

.teste2, .teste3 {

color: blue;

}

.teste2 {

font-weight: normal;

}

.teste3 {

font-weight: bold;

}

CSS Gerado.teste, .teste2,

.teste3{

color: blue;

}

.teste2 {

font-weight: normal;

}

.teste3 {

font-weight: bold;

}

VS.

MIXINS

@mixin absolute-full-size{

position: absolute;

top: 0;

bottom: 0;

left: 0;

right: 0;

}

SCSS

.content{

@include absolute-full-size;

}

MIXINS

.content {

position: absolute;

top: 0;

bottom: 0;

left: 0;

right: 0;

}

CSS Gerado

MIXINS - PARÂMETROS

@mixin absolute-full-size($spacement){

position: absolute;

top: $spacement;

bottom: $spacement;

left: $spacement;

right: $spacement;

}

SCSS

.content{

@include absolute-full-size(10px);

}

MIXINS - PARÂMETROS COM VALOR

DEFAULT

@mixin absolute-full-size($spacement: 0){

position: absolute;

top: $spacement;

bottom: $spacement;

left: $spacement;

right: $spacement;

}

SCSS

.content{

@include absolute-full-size(10px);

}

MIXINS - PARÂMETROS NOMEADOS

@mixin tile-dimensions($horizontal-slots: 1,

$vertical-slots: 1){

width: $horizontal-slots * 120px;

height: $vertical-slots * 120px;

}

SCSS

.news-widget {

@include tile-dimensions($horizontal-slots: 3,

$vertical-slots: 2);

}.news-widget {

@include tile-dimensions($vertical-slots: 2,

$horizontal-slots: 3);

}

MIXINS - DIRETIVA @content

@mixin tile-center-icon{

.icon-center{

@content;

}

}

SCSS

.config-tile{

@include tile-center-icon{

@include fa-cogs; //Font-awesome icon…

}

}

MIXINS - QUANDO USAR?

@mixin absolute-full-size{

position: absolute;

top: 0;

bottom: 0;

left: 0;

right: 0;

}

SCSS

.content{

@include absolute-full-

size;

}

.absolute-full-size{

position: absolute;

top: 0;

bottom: 0;

left: 0;

right: 0;

}

.content{

@extend .absolute-full-

size;

}

VS.

MIXINS VS. EXTENDS

Mixins podem receber parâmetros Classes extendidas sempre se comportarão da mesma forma

Mixins precisam ser declarados antes de serem chamados

Extends devem ser usados para compartilhar estilos iguais entre regras

Mixins consiste em reaproveitamento de regras

Mixins consiste em reaproveitamento de regras e valores

Mixins não suportam referências cíclicas (mixin A inclui mixin B que inclui A)

Duas regras podem se estender mutuamente sem problema algum (apesar de não indicado)

Mixins devem ser usados para compartilhar estilos similares entre regras

Classes extendidas podem estar em qualquer lugar do código

MIXINS

Exemplo de mixins úteis.

FUNCTIONS

@function calcular($val: 5px) {

@return $val * 2;

}

margin-right: calcular(10px);

FUNCTIONS

@function tamanho-tile($slots: 1) {

$tamanho: $tamanho-padrao * $slots;

@if $espacamento-padrao > 0{

$tamanho: $tamanho + ($espacamento-padrao * $slots – 1);

}

@return $tamanho;

}

width: tamanho-tile(3);

height: tamanho-tile(2);

FUNCTIONS VS. MIXINS

Functions retornam um único valor Mixins não possuem retorno

Functions não podem conter propriedades CSS e obviamente nem regras. Elas apenas efetuam alguma espécie de processamento e retornam um resultado.

Mixins podem conter não apenas lógica (através das diretivas de controle), como propriedades CSS, ou até regras inteiras. As quais podem ser rederizadas nos pontos onde o mixin é chamado.

A declaração e a chamada de uma function exige parênteses. Independente de ela não possuir argumentos.

Mixins sem argumentos podem ser declarados e invocados sem parênteses

LET’S CODE!

FUNÇÕES NATIVAS - lighten

Ilumina uma cor

//Ilumina a cor preta em 10%

lighten(#000, 10)//=>#1A1A1A

A função lighten intensifica os três canais RGB

igualmente

FUNÇÕES NATIVAS - darken

Escurece uma cor

//Escurece a cor azul em 20%

darken(blue, 20)//=>#000099

A função darken reduz os três canais RGB

igualmente

FUNÇÕES NATIVAS - grayscale

Converte uma cor para a sua equivalente

em escala de cinza

grayscale(red)//=>#808080

FUNÇÕES NATIVAS - mix

Mistura duas cores de acordo com um peso

//Mistura as cores preto e branco

mix(black, white)//=>#7F7F7F

//Resulta em uma mistura com 10% de

//preto e 90% de branco

mix(black, white, 90)//=>#191919

Quanto mais alto o valor do peso, mais a cor

passada como segundo parâmetro irá predominar

na mistura.

FUNÇÕES NATIVAS - transparentize e

opacifyTorna uma cor transparente de acordo com

um determinado percentual

//Um azul 30% transparente, ou 70% opaco

transparentize(blue, 0.3)

A sua contrapartida é a função opacify

$cor: transparentize(blue, 1)

//Um azul 30% opaco, ou 70% transparente

opacify($cor, 0.3)

FUNÇÕES NATIVAS - scale-color

Cria uma nova cor com base em outra existente,

ajustando cada canal

//Aumenta os canais R e G em 10% e reduz o canal B em 20%

scale-color(blue, $red: 10%, $green: 10%, $blue: -20%)//=>#1919CC

http://goo.gl/F4BeyX

FUNÇÕES NATIVAS - if TERNÁRIO

Função que age de forma semelhante ao if

ternário em outras linguagens

//Se $dark-layout for true, $cor

//será #000

$cor: if($dark-layout, #000, #FFF);

$cor2: if(10 > 5 and 4 <= 7, #000, #FFF);

FUNÇÕES NATIVAS - unquote

Converte uma string quoted (com aspas) em

uma string sem aspas

$borda: “solid 1px #000”;

a { border: unquote($borda); } // a { border: solid 1px #000; }

A sua contrapartida é a função quote$carro: ferrari;

a { content: quote($carro); } // a { content: “ferrari”; }

FUNÇÕES NATIVAS - nth

Obtém um item de uma lista de acordo com

sua posição

$cor: nth(5px 5px 10px #FBD, 4);//#FBD

Listas em Sass são 1-based

FUNÇÕES NATIVAS - length

Retorna o tamanho de uma lista

$margens: 10px 5px 15px 0;

if(length($margens) > 0)... //length retorna 4

FUNÇÕES NATIVAS - index

Retorna a posição de um item em uma lista

$margens: 10px 5px 15px 0;

index($margens, 5px) //index retorna 2

FUNÇÕES NATIVAS - unit

Retorna a unidade de um valor numérico

unit(10px)//=> “px”

unit(120deg)//=> “deg”

unit(800ms)//=> “ms”

FUNÇÕES NATIVAS - unitless

Testa se um valor numérico possui unidade

@mixin tamanho-texto($tamanho){

@if(unitless($tamanho)){

$tamanho: "#{$tamanho}px";

}

font-size: unquote($tamanho);

}

h1{

@include tamanho-texto(30);

}

COMPASS config.rb

Retém todas as configurações do compass

# sass_path: the directory your Sass files are in. THIS file

should also be in the Sass folder

sass_path = File.dirname(__FILE__)

output_path = File.expand_path(File.join(sass_path, '../CSS'))

# css_path: the directory you want your CSS files to be.

css_path = output_path

# output_style = :expanded or :nested or :compact or :compressed

output_style = :expanded

http://goo.gl/JMm6Zh

ALT TAB...

http://goo.gl/YmQSez

COMPASS STATISTICS

Retorna estatísticas sobre um projeto compass

$ compass stats

SEGUINDO EM FRENTE...

Bourbon - http://bourbon.io

Compass Recipes - http://compass-recipes.moox.fr

Todas as funções do Sass - http://goo.gl/jdDkiE

DICAS ADICIONAIS...

BEM – Block, Element, Modifier - http://goo.gl/QpBJFo

Color Me - http://richbray.me/cms/usage/

Sassy Buttons - http://jaredhardy.com/sassy-buttons/

Normalize - http://goo.gl/kqpTv2