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...
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!
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:
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:
- Faltou um
;
entre color e font-family - o compilador deveria, inclusive, dar pau numa dessas! - Bobeira: pessoalmente prefiro a conveção
StyledComponentName
pra styled components...CustomSemiTitle
me faz pensar que ele é especial e tem outroSemiTitle
, sei lá, boto fé que é viagem mas acho legal escolher racionalmente uma convenção de nomenclatura desses trem; - 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 umfont-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!
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 ;)
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:
- 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.
- Escrever o tamanho da fonte em quase todo componente, o que deixa o código maior e o processo mais chato;
- 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