Skip to content

Instantly share code, notes, and snippets.

@luan0ap
Forked from threepointone/0 basics.md
Last active January 31, 2020 03:30
Show Gist options
  • Save luan0ap/37f926ed8db620b8aedce2d586621fe5 to your computer and use it in GitHub Desktop.
Save luan0ap/37f926ed8db620b8aedce2d586621fe5 to your computer and use it in GitHub Desktop.
css-in-js - em português

Uma série de posts sobre CSS in JS

0. Estilos como objetos

Primeiramente, um exercicio. Podemos representar o CSS como texto puro? Bora tentar:

let redText = { color: 'red' };

Show de bola, deve ser claro o que este código acima deve "fazer" né. então bora tentar de novo:

let boldText = { fontWeight: 'bold' };

Ainda bastante clean. Podemos mudar o camelCase por nomes de proprieades (sendo o oposto dos hífens no CSS), mas isso é de boas no JS, até por que usamos isso sempre na declaração de variáveis e funções. Se liga no exemplo abaixo;

let boldRedText = { ...redText, ...boldText };

Nada de mais, it's "just javascript" (:v). Você pode pode dar aquele famoso console.log para ver um resultado incrível haha

console.log(boldRedText);
// { color: 'red', fontWeight: 'bold' }

Mas e que tal combinar o exemplo acima com um array? Bora tentar:

let boldRedText = [redText, boldText];

console.log(boldRedText);

// [{ color: 'red' }, { fontWeight: 'bold' }]

Essa representação tem a vantagem de preservar as peças e a ordem que compõem o estilo, o que é bom para a depuração, além de ser mais eficiente para o computador manipular (vamos mergulhar nas otimizações em um post posterior).

Desse modo podemos manter algumas vantagens de preservarmos as ordens que compõem do nosso style, sendo cool pra depuração, além das vantagens performáticas. (Veremos mais sobre isso no decorrer dos posts).

Podemos deixar isso mais interessante extendendo esse objeto, adicionando pseudo seletores:

let redGreenText = {
  color: 'red',
  ':hover': {
    color: 'green',
  },
};

Espera-se que fique claro o que este objeto representa - um texto em estilo de texto que é vermelho por padrão e verde quando pairado. Como antes, isso compõe bem.

Código acima deve ser bastante claro para alguns, mas caso ainda tenha suas dúvidas ele básicamente vai ser um texto que por padrão é verde, mas quando receber o evento de hover (cursor em cima do elemento) ele recebe uma cor verde. Segue um sample abaixo:

let composed = [redGreenText, boldText];
/*
[{
  color: 'red',
  ':hover': {
    color: 'green'
  }
}, {
  fontWeight: 'bold'
}]
Deve ser equivalente a isto -

{
  color: 'red',
  fontWeight: 'bold',
  ':hover': {
    color: 'green'
  }
}
*/

Mas e se quisermos um texto bold somente no eveto hover. Nós podemos fazer isso da seguinte forma:

let composed = [redGreenText, { ':hover': boldText }];
/*
this would be equivalent to -
{
  color: 'red',  
  ':hover': {
    color: 'green',
    fontWeight: 'bold'
  }
}
*/

Nice!

Podemos fazer muito mais que pseudo classes. Quem é do Sass/Less vai se sentir em casa com contextuais seletores

let translucentRed = {
  backgroundColor: 'rgba(255, 0, 0, 0.8)',
  '.ie6 &': {
    backgroundColor: 'red',
  },
};

Traduzindo seria assim "A cor de fundo é um vermelhos meio opaco, mas se tiver um pai com a classe .ie6 ele recebe um vermelho normal"

Da mesma forma, podemos adicionar suporte para consultas @ media e blocos @ support. Um exemplo artificial mostrando todos eles em um objeto 111

Podemos adicionar o suporte para o famoso @media e @supports. Algo assim:

let page = {
  color: 'red',
  ':hover': {
    color: 'blue',
  },
  '@media screen': {
    color: 'blue',
    '@supports (display: flex)': {
      color: 'yellow',
    },
  },
};

Sinta-se a vontade para alinhar arbitrariamente e profundamente, com todo tipo de combinação de seletores e outras coisas.

Finalmente, as vezes, se você desejar produzir vários valores para um propriedade / fallbacks. É normal definir isso com arrays. Por exemplo, suponha que você precise de um backgorund vermelho opaco em navegadores que tenham suporte rgba() e um vermelho normal para navegadores do passado.

let style = {
  color: ['red', 'rgba(255, 0, 0, 0.8)'],
};

Com essas poucas regras, podemos escrever um css irado que visam a especificação entire css, sem exeções.

Pois isso é VanillaJS, sem dependências de outros para você dar aquele famoso import, sendo possvel rodar em qualquer ambiente JS. E olha só que legal, você pode checar tipo com flow/typescript/etc.

E é totalmente possível implementar arquiteturas CSS clássicas como: itcss, smacss, oocss, bem. E sem nenhuma restrição com o Sass ou o Less. E como tudo aqui é dinâmico podemos fazer algumas abstrações bem maneiras como glamorous/styled-components, jsxstyle. Falaremos um pouco mais disso em um post futuro.

Até agora tá tudo certo, mas... Onde colocamos esses estilos?

Vamos assumir que temos uma função mágica, css(), isso pega qualquer um desses objetos e nos retorna um nome de classe.

let cls = css({color:'red'});
let html = `<div class='${cls}'> this is red! </div>`;
// <div class='css-1sdfpa'> this is red! </div>

E é isso haha. Não precisamos aprender mais nada, isso ajuda muio com o resto do seu ecosistema/workflow/ferramentas. Genial!

No próximo post nós iremos aprender um pouco mais, sobre o que o css() faz por baixo dos panos.

Esse post foi uma tradução livre sendo parte 0 de uma sequência de artigos em inglês escrita por threepointone

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment