Skip to content

Instantly share code, notes, and snippets.

@hdoro
Last active July 13, 2018 16:04
Show Gist options
  • Save hdoro/0a9d941bb606e41890949cdc384ac591 to your computer and use it in GitHub Desktop.
Save hdoro/0a9d941bb606e41890949cdc384ac591 to your computer and use it in GitHub Desktop.

Feedback front Nata

CSS e afins

[🔔 NOVA] Incluir mais "fallbacks" para as fontes

Primeiramente, mandaram muito em aplicar as mudanças propostas! O que acharam, fez sentido?

Uma coisa que percebi nessa implementação foi que vocês só incluiram a sans-serif como fonte "fallback" pro heading:

$font__heading: 'ProximaNovaAltBold';
$font__base: sans-serif;

// Cor dos cabeçalhos
h1,h2,h3,h4,h5,h6 {
  color: $font-color_heading;
  font-family: $font__heading, $font__base;
}

Isso funciona, mas tem um grande problema: se o cliente não conseguir carregar a Proxima Nova por algum motivo, o site INTEIRO vai tá rodando em sans-serif, e bem, acho que a foto abaixo fala por si mesma...

Design com sans-serif

O design fica todo descaracterizado com essa fonte, ela é a fonte mais sem graça possível, a sem serifa mais longe da Proxima Nova possível... A solução? Manda o $font__base: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif!

Esse set de fonts fallback permitem que você use as novas fontes dos sistemas operacionais - a São Francisco pro Mac, Roboto pro Chromebook e a Segoe pros Windows, e ainda oferece outras melhorzinhas como ubuntu e Open Sans que os dispositivos da galera podem ter. Se você der uma olhada nessas famílias de fontes, elas são muito mais agradáveis e próximas (nova... ba dum tsss)! Se quiser fritar um cado, tem um post da galera do Medium falando como eles migraram toda a UI deles pra fontes nativas de sistema, é massa!

[🔔 NOVA] Centralizar o uso de fontes

Quando fui tirar o print com tudo em sans-serif eu percebi como tava pulverizada a definição de fontes... tive que trocar as fontes em uns 5 ou 6 seletores de css diferentes, com alguns exemplos como o abaixo:

Componente aleatório com definição de fonte

Aí fui descobrir que esse componente era o <SemiTitle>:

export default class SemiTitle extends Component {
  render() {
    return <CustomSemiTitle {...this.props} />;
  }
}

const CustomSemiTitle = styled.h5`
  margin: 0.5rem 0;
  color: ${props => props.theme.colors.text}
  font-family: ${props => props.theme.fonts.semibold}
`;

Alguns problemas com isso:

  1. Faltou um ; entre color e font-family - o compilador deveria, inclusive, dar pau numa dessas!
  2. Bobeira: pessoalmente prefiro a conveção StyledComponentName pra styled components... CustomSemiTitle me faz pensar que ele é especial e tem outro SemiTitle, sei lá, boto fé que é viagem mas acho legal escolher racionalmente uma convenção de nomenclatura desses trem;
  3. Você definiu uma família de fonte ancorada no tema, mas aí se num próximo componente você vai precisar fazer o mesmo, o que tem seus problemas:
  • É um saco escrever font-family: ${props => props.theme.fonts.semibold} toda vez;
  • Se for fazer SSR (não se aplica ao Finspect, no caso), isso vai gerar um CSS extra meio desnecessauro;
  • E o props.theme.fonts.semibold sequer tem uma fonte fallback, então se a ProximaNova não baixar, o componente vai ficar em branco, sem texto aparecendo, isso é gravíssimo! Ou você incluiria o fallback na própria variável ou mandaria um font-family: ${props => props.theme.fonts.semibold + props.theme.fonts.fallback }, que é ainda mais chato de escrever

Ao invés disso, o que eu sugiro é criar uma helper class no typography.scss que contém essa fonte:

$font__semi: 'ProximaNovaSemibold';

.font_semi {
  font-family: $font__semi, $font__base;
}

E no componente eu removeria aquela linha e mandaria um className="font_semi":

export default class SemiTitle extends Component {
  render() {
    return <StyledSemiTitle className="font_semi" {...this.props} />;
  }
}

const StyledSemiTitle = styled.h5`
  margin: 0.5rem 0;
  color: ${props => props.theme.colors.text};
`;

Esse jeito de pulverizar o CSS numas classes miniaturas que você vai usar regularmente é bem prático pra algumas coisas... pra outras, como um normalizer de um botão que vai tirar a borda, background e outros estilos feios padrão dos browsers, você pode usar o styled components da seguinte maneira:

// styles/helpers.js
export const buttonNormalizer = `
  background: transparent;
  border: none;
  font-size: 1rem;
  cursor: pointer;
`;

// components/LikeButton.jsx (componente fictício)
import { buttonNormalizer } from '../styles/helpers';

const StyledButton = styled.button`
  // entramos com o string do buttonNormalizer dentro
  // do estilo desse componente
  ${buttonNormalizer} // incluir ; se o buttonNormalizer não fechar com isso
  
  // e aplicamos os estilos específicos desse componente
  padding: .5em;
`;

Você pode fazer isso pra funções também... no projeto da 2origins eu tava de saco cheio de escrever width: x; height: y, então criei uma função basicona:

// styles/helpers.ts
export const widthHeight = (w: string, h?: string) => `width: ${w}; height: ${h ? h : w}`;

export const absCenter = `
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
`;

// components/Componente.tsx
import { absCenter, widthHeight } from '../styles/helpers'

const StyledComponente = styled.div`
  ${absCenter}
  ${widthHeight('1rem')} // largura e altura iguais numa linha só ;)
`;

Não tô falando pra usar isso sempre, o exemplo da largura / altura pode parecer excesso, abrir uma função no meio do string, importar a função... pode ser enfadonho! Mas fica a ideia pra você aplicar quando perceber que tá repetindo demais uma coisa em específico... e ao final do projeto você vai ter o começo de uma snippet library pra vocês usarem em projetos futuros!

Usar ems ou rems ao invés de px

Um bom exemplo de quando isso seria muito positivo: botões

const DefaultButton = styled(BootstrapButton)`
  ...
  border-radius: 20px;
  padding: 6px 30px;
  ...
`;

No código acima, o padding do botão não é ancorado no tamanho da fonte, então se você precisar criar uma variação de botão que seja menor ou maior - pra dar maior destaque, encaixar numa seção maior, ou o que for, você vai precisar atualizar esses valores de padding pra ele não ficar muito grande:

const SmallButton = DefaultButton.extend`
  font-size: .9rem;
  border-radius: 18px;
  padding: 5px 27px;
`;

São necessárias 3 linhas só pra mudar o tamanho do botão... isso tá longe de ser ideal, sem contar que exige um esforço de calcular as proporções de acordo com a variação no tamanho da fonte, é um saco. Ao invés disso, se você definir o tamanho da fonte e ancorar essas medidas em em, em que 1 em = 1 * (tamanho da fonte do elemento mais próximo com tamanho de fonte definido), você consegue mandar um componente muito mais enxuto:

const DefaultButton = styled(BootstrapButton)`
  ...
  ${props => props.isBig ? 'font-size: 1.3rem' : 'font-size: 1rem'}
  border-radius: 1em;
  padding: .3em 1.5em;
  ...
`;

E pronto! A proporção padding e o border-radius vão se manter sempre de acordo com o que você quer, independente do tamanho da fonte do botão. No exemplo acima eu tratei como se 1rem, que é o tamanho da fonte da raíz do documento, setada por :root: { font-size: 20px }), fosse igual a 20px... a base dos ems e rems sempre se dá em px ;)

🚨🚨 Padronizar as cores, fontes e tamanhos via css global e a unidade rem

Eu percebi que no componente components/NavLink.jsx vocês escreveram:

const CustomNavLink = styled(BootstrapNavLink)`
  ...
  color: #4f5367;
  font-size: 16px;

  ...
`

Isso é bastante grave e vai gerar MUITO retrabalho e inconsistência no produto final, falo por experiência própria...

O problema é que toda vez que vocês quiserem definir um componente vocês vão ter que:

  1. necessariamente se lembrar quais são as cores a serem utilizadas e copiar elas quando for usar. Sei que vocês usam o tema do Bootstrap pra passar algumas cores, mas isso só parece ter sido usado pra cor primária e secundária, quando na verdade deveria englobar tudo: cor auxiliar, tons de cinza, cor de alerta, etc.
  2. Escrever o tamanho da fonte em quase todo componente, o que deixa o código maior e o processo mais chato;
  3. Procurar lugares da aplicação em que houve alguma incosistência - querendo ou não elas acontecem, e o Finspect não é uma plataforma pequena, o trabalho vai ser grande.

Ao invés disso, eu sugiro vocês criarem um styled components global ou importar uns arquivos .sass, .styl ou .css com elementos genéricos, formatando a base do documento pros estilos do Finspect. Pode contar comigo pra ajudar nisso! Por exemplo, eu costumo sempre criar um elements.sass que contém o seguinte:

\:root
  font-size: $font-size

*, *::before, *::after
  box-sizing: inherit
  font-family: inherit
::selection
  background: transparentize($color__primary,.3)
  color: white
html
  box-sizing: border-box
  overflow-x: hidden
  color: $font-color
  font-family: if($font__body != null, ($font__body, $font__base), $font__base)
  ::-webkit-scrollbar
    width: 3px
  ::-webkit-scrollbar-thumb
    background: $color__primary

body
  margin: 0

a
  color: $color__link
  transition: $transition__duration opacity $transition__function
  &:hover
    opacity: .8

button
  font-family: inherit
  font-size: 1rem

img
  display: block
  max-width: 100%
  margin: leading(1.5) auto
...

Essas variáveis eu defino em outros arquivos, centralizando tudo. Tem também o arquivo typography.sass que define os estilos de elementos de texto:

// Cor dos cabeçalhos
h1,h2,h3,h4,h5,h6
    color: $font-color_heading
    font-family: $font__heading, $font__base

// Loop pros headings, gerando as propriedades corretas de acordo com as propriedades definidas em cada objeto
@each $heading, $properties in $headings
    #{$heading}
        font-size: remize(nth($properties, 1))
        line-height: leading(nth($properties, 2))
        margin: params(false,nth($properties, 3),0,nth($properties, 4))

// não frita muito nessas funções remize, leading, e etc.
// são usadas só pra ancorar tudo em rems, posso criar esse
// arquivo pra vocês, sento com o Vitor e a gente já cria
// tudo de acordo com o design do Finspect

// Definições para parágrafos
p
  font-size: 1rem
  line-height: leading(1)
  margin: params(false, 1, 0, 1)
  color: inherit
  max-width: $max-width
  // algumas classes utilitárias pra posicionamento e tamanho
  &.text_right
    text-align: right
    margin-right: 0
    margin-left: auto
  &.text_center
    text-align: center
    margin-right: auto
    margin-left: auto
  &.text_sm
    font-size: .8rem
  &.text_lg
    font-size: 1.2rem

...

Pro styled components e o JS, eu crio um theme.js mais ou menos nessa linha:

export const theme = {
  colors: {
    primary: '#F04140',
    success: '#3DC670',
    text: '#474747',
    greyLight: '#e1e1e1',
    greyBluish: '#dfe6e9',
    greyMed: '#636e72',
  },
  boxShadow: {
    default: '0 4px 4px rgba(0,0,0,.24)',
    low: '0 2px 2px rgba(0,0,0,.16)',
    raised: '0 6px 6px rgba(0,0,0,.32)',
  },
  transitions: {
    default: '.25s ease',
    fast: '.15s ease',
    slow: '.45s ease',
  }
};

e aí na hora de criar um component eu mando:

import { theme } from '[CAMINHO]';

...

const Button = styled.button`
  color: ${theme.colors.primary};
  box-shadow: ${theme.boxShadow.default};
  transition: ${theme.transitions.default} color;
`;

E como o tamanho de fonte já vai estar definido no elements.sass, eu só preciso mexer nele se precisar mudar alguma coisa, bem mais tranquilo! Não conheço tanto do Bootstrap e o ThemeProvider dele, mas imagino que essa seja a ideia, não importa como cês forem implementar, só implementa kkkkkk

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