Static
Esta pasta contém todos os arquivos de estilo (css e scss), arquivos de comportamento JavaScript, imagens incluídas no layout e o arquivo checkout.scss.tpl.
CSS
Lógica
Em nosso layout Base, usamos o Bootstrap 4 como uma estrutura geral, usando apenas o grid: https://getbootstrap.com/docs/4.3/layout/grid/ e as “classes de utilitários”. Seguindo as diretrizes que propõe:
- Organização da coluna: 12
- Mobile first e media queries para desktop
- Estrutura de containers - row - col
- Uso de helpers/utilities
Nós usamos a mesma lógica para nossos próprios elementos. Atribuímos um nome para encapsular um componente que chamamos de bloco, que contém elementos (element) com a possibilidade de terem variantes (modifier). Os três termos são separados por meio do hífen. Por exemplo:
.page{} .page-title{} .page-title-primary{}
Este bloco é o componente que constrói a Página (page). Seu elemento interno é o Título (title) que contempla as propriedades gerais, tais como: posição, família de fontes, padding, margin; e finalmente o modificador “primary” que poderia modificar ou adicionar variações, como: cor e tamanho.
Pode haver elementos independentes dos blocos, como um botão:
.btn{} .btn-primary{}
Usamos os nomes dos componentes para as classes para poder reutilizá-los e não trabalhar com nomes apontados para características específicas.
Por exemplo:
Não utilizamos nome de funcionalidades
.billing-card { }
Utilizamos nome do componente
.card { } .card-primary { } .card-secondary { }
Há exceções nas quais os nomes podem ser mais específicos, pois são usados apenas em um lugar.
Além de ter classes para componentes e variações por meio de modificadores, temos classes chamadas "helpers" ou "utilities", que geralmente têm apenas 1 propriedade e as usamos para aplicar uma exceção às propriedades do componente.
Por exemplo, temos um componente para títulos que possui a propriedade “text-align: center” para que seu conteúdo seja sempre centralizado:
.page-title{ css-property; css-property; css-property; text-align: center; }
<h1 class=”page-title”>Título</div>
Mas, em uma tela específica, precisamos que esse título esteja alinhado à esquerda. Para isso, não vamos criar uma nova classe, mas vamos usar um helper:
<h1 class=”page-title text-left”>Título</div>
Temos que ficar bem claro que o uso de um Helper responde a uma exceção à regra. Do contrário, seria conveniente criar um novo elemento ou uma nova variação para que isso não aconteça:
<h1 class=”page-title mt-1 mb-1 text-left bg-red color-primary”>Título</h1>
Também usamos SASS, especialmente para propriedades como cores, fontes e configurações que são repetidas em diferentes elementos e componentes.
No arquivo SASS style-colors.scss.tpl salvamos as cores e fontes configuradas na seção ‘Personalizar seu layout atual’ no Administrador Nuvem e aplicamos a todos os estilos necessários:
{# /* // Colors */ #} $primary-color: {{ settings.primary_color }}; $main-foreground: {{ settings.text_color }}; $main-background: {{ settings.background_color }}; {# /* // Font families */ #} $heading-font: {{ settings.font_headings | raw }}; $body-font: {{ settings.font_rest | raw }};
Também aproveitamos o SASS para aninhar componentes e funções, como:
@mixin prefix($property, $value, $prefixes: ()) { @each $prefix in $prefixes { #{'-' + $prefix + '-' + $property}: $value; } #{$property}: $value; } a { color: $main-foreground; @include prefix(transition, all 0.4s ease, webkit ms moz o); &:hover, &:focus{ color: rgba($main-foreground, .5); } }
Tips
Aqui estão algumas boas práticas para manter seu código limpo e organizado.
- Como a memória sempre falha, tentamos comentar tudo o que podemos, explicando cada seção e esclarecendo cada estilo. Em nossos .tpl, os comentários são inseridos da seguinte forma:
{# /* Comentario */ #} - As folhas de estilo possuem um índice inicial para classificar os componentes e localizá-los mais rapidamente.
- Não usamos ID para identificar elementos, pois existem algumas funções que usam IDs.
- Não aplicamos CSS a elementos básicos como “div.” Ou “p.”. Exceto os títulos: h1, h2, h3, etc.
- Evitamos usar nomes e variações de elementos que sejam específicos demais para não estarem relacionados a algo que pode mudar. Por exemplo, as cores.
- Nós não usamos CSS para classes que começam com js-, já que estas funcionam com JavaScript.
- Seguimos um guia para manter a ordem e a lógica do nosso CSS: https://codeguide.co/#css em toda a ordem de propriedades: https://codeguide.co/#css-declaration-order
Utilização:
Na pasta CSS você pode encontrar os três arquivos que dão todos os estilos ao layout.
Os estilos são separados em três arquivos diferentes pelos seguintes motivos:
- Prioridade (crítica e não crítica)
- Formato
- Conteúdo
style-critical.tpl
Este arquivo contém todos os estilos críticos para a exibição correta da loja "Above the fold". É adicionado inline dentro do DOM para carregar antes de qualquer outra coisa e o formato no qual está escrito é CSS simples.
style-colors.scss.tpl
Este .tpl contém todos os parâmetros de cor e fontes da loja no formato SCSS. É crucial que, desde o primeiro momento, os usuários vejam a loja com as cores e fontes institucionais da marca, por isso ela funciona de forma síncrona, carregando antes do restante do HTML.
style-async.scss.tpl
Esse é o único arquivo de estilo que é carregado de forma assíncrona e contém todos os estilos e parâmetros que não são necessários para a criação e visualização do design na primeira instância (como: estilos aplicados a maneiras ou menus suspensos). Ele é criado no SCSS, e para que sua carga seja assíncrona, ele é incluído em um arquivo JS (“load-css-async.tpl”) que é chamado a partir do layout.tpl:
load-css-async.tpl:
<script id="style-css"> loadCSS( '{{ 'css/style-async.scss.tpl' | static_url }}', document.getElementById("style-css")); </script>
layout.tpl:
{% include "static/js/load-css-async.tpl" %}
Para entender essa priorização de estilos, você pode ver o artigo CSS + Performance
checkout.scss.tpl
Finalmente, há outro arquivo CSS que está fora da pasta CSS, mas dentro do Static. Aqui você pode adicionar ou modificar CSS para o checkout, apenas que para aplicar essas alterações você deve ativar a opção "Cores do checkout" na seção Configurações/Opções de checkout do administrador.
JS
Lógica
Os arquivos JavaScript são fundamentais para a operação de nossas lojas, bem como para gerar comportamentos atrativos do design.
Mantemos todo o nosso código interno de JS, os quais criamos para determinadas funções no fluxo de compra da loja, separados dos códigos fornecido por plugins e aplicativos externos.
Usamos o jQuery por padrão e alguns plugins de código aberto que nos dão flexibilidade ao desenvolver novos layouts. Dependendo da dependência com o jQuery, vamos colocar as funções em diferentes .tpls
- external-no-dependences.js.tpl - não precisam do jQuery para funcionar
- external.js.tpl - precisam do jQuery para funcionar
- store.js.tpl - funções próprias (interno)
Por outro lado, temos uma parte do código JS que é privado. Não pode ser modificado e não está disponível na estrutura do layout.
Este código privado tem as funções fundamentais da Nuvemshop, e você pode identificá-las porque elas começam com "LS". Muitos deles têm a ver com o controle do catálogo de produtos, meios de pagamento e meios de envio.
Neste arquivo, determinamos algumas funções importantes que podem ser usadas publicamente, como as seguintes:
LS.ready.then - Aguarde até que o jQuery carregue para ver o que está dentro desta função.
LS.ready.then(function(){ {# Libraries that requires Jquery to work #} {% include "static/js/external.js.tpl" %} {# Specific store JS functions: product variants, cart, shipping, etc #} {% include "static/js/store.js.tpl" %} });
LS.addToCartEnhanced - Quando um produto é adicionado ao carrinho.
function changeVariant (variant) - Quando outra variante é selecionada em um produto. É usado, por exemplo, para atualizar o preço se uma variante for mais cara que a outra.
LS.calculateShippingAjax - Ao calcular o custo de envio.
Tips
Algumas recomendações que podemos lhe dar:
- As classes que possuem um prefixo “.js-” estão sempre associadas a um comportamento JavaScript. Se você excluir algum, confirme se ele não afeta o fluxo de compra.
- Sempre que um código js for adicionado, respeite o índice de cada arquivo. Manter o código ordenado facilita o entendimento e a correção de erros.
- Localize os plugins nos arquivos external.js.tpl e, de acordo com a dependência do jQuery, adicione-o em external-no-dependencies.js.tpl
- O JS gera um dos principais problemas para manter o desempenho de nossas lojas, e por isto é necessário certificar-se de não carregar desnecessariamente nas seções que não são utilizadas. Para isso, você pode usar condicionais Twig como:
- {% if template == 'product'%} - CODE javaScript - {% endif%} para que apenas este código seja carregado nos detalhes do produto.
- Para mais informações sobre desempenho e JavaScript, você pode visitar o seguinte artigo
Utilização
Externals JS
external.js.tpl
Este arquivo contém os seguintes códigos:
Jquery.cookie v1.4.1 - Usado para determinar com que frequência uma ação deve ser acionada. Usamos para o popup da newsletter.
Site do autor: https://plugins.jquery.com/cookieJquery.livequery v1.3.6 - Usado para executar funções do jQuery em tempo real. Nós o usamos na calculadora de frete.
Site do autor: https://plugins.jquery.com/livequery/Fancybox 3.3.1 - Plugin para ampliar imagens gerando um modal com diferentes opções. Usamos este plugin nas imagens de detalhes do produto.
Site do autor: https://www.fancyapps.com/fancybox/3/Neste caso, você verá que o código é formado pela seguinte condição: {% if template == 'product'%} {% endif%}. Isso significa que ele será carregado apenas para a tela de detalhes do produto, pois é o único local onde esse plug-in é usado.
Ele também é contido por {% raw%} {% endraw%}. Isto é necessário já que, sendo um arquivo .tpl, alguns códigos JS possuem uma sintaxe conflitante com o Twig, portanto, tudo o que está contido nessa tag não contemplará nenhum método ou função Twig.
Admin.externalcode - essas linhas chamarão os códigos personalizados que o administrador da loja pode adicionar em "Configurações> Códigos externos"
external-no-dependencies.js.tpl
Este arquivo contém os seguintes plugins:
Lazyload - É uma biblioteca com diferentes recursos que contemplam o carregamento progressivo e a priorização do carregamento de imagens. Usamos isso para otimização de desempenho em relação ao carregamento de imagens. Para mais informações você pode visitar nosso artigo de Imagens - Performance
Site do autor: https://github.com/aFarkas/lazysizes https://github.com/verlok/lazyloadInstafeed - Usamos para mostrar as postagens mais recentes do Instagram em cada loja. Ele é contido pelo condicional {% if settings.show_instafeed e (template == 'home')%}, de forma que só é carregado na página inicial e com o componente ativado no administrador → Personalizar o layout atual.
Site do autor: http://instafeedjs.com/Swiper 4.4.2 - É um plugin dedicado para Sliders. Usamos para todos os carrosséis da loja: carrossel de imagens, carrossel de produtos, produtos relacionados, imagens de detalhes de produtos.
Site do autor: https://idangero.us/swiper/
CSS async JS
Em seguida, encontraremos um .js para inserir as folhas de estilo de forma assíncrona. Se você está interessado em saber como fazê-lo, nós o descrevemos acima.
Este arquivo contém a função e, em seguida, o CSS chama da seguinte maneira:
<script id="font-awesome-css"> loadCSS( '{{ 'font-awesome/font-awesome-5.css' | static_url }}', document.getElementById("font-awesome-css")); </script> <script id="style-css"> loadCSS( '{{ 'css/style-async.scss.tpl' | static_url }}', document.getElementById("style-css")); </script>
Sempre que precisarmos atribuir funcionalidade a um elemento HTML, usaremos classes com o prefixo “js-”. A partir deste arquivo, não usamos identificadores ID. Por exemplo, por modos, definimos variáveis destinadas a elementos com as classes “.js-modal-close” e “.js-modal-open”
var $modal_close = $('.js-modal-close'); var $modal_open = $('.js-modal-open');
Images
Imagens
As lojas estão cheias de imagens, já sabemos disso. Desde imagens publicitárias de banners, carrosséis, feeds do Instagram até as próprias imagens dos produtos.
Podemos começar a falar sobre imagens gerenciáveis e não-administráveis. As primeiras são todas aquelas que são carregadas do Store Manager, tanto de um produto quanto da seção "Personalize seu design atual".
E as não-administráveis são as que definimos a partir do código diretamente no layout. Este último, será encontrado na pasta static/images, onde são chamados a partir dos diferentes arquivos com HTML.
O tamanho das imagens é o original da imagem que é carregada pelo FTP, então você deve ter muito cuidado em sua otimização, uma vez que podemos prejudicar muito o desempenho da loja com o peso de uma imagem muito pesada
Você pode fazer upload de imagens em .png, .jpg e .gif e através dos arquivos html, chamaremos essas imagens da seguinte maneira:
{{ "imagen.jpg" | static_url | img_tag (store.name) }}
O ALT de uma imagem pode ser passado como um parâmetro entre aspas
img_tag("<strong>Twitter</strong>")
Por outro lado, as imagens que são uploaded pelo Administrador Nuvem têm outro comportamento. Quando uma imagem é carregada, ela é salva em tamanhos diferentes que podemos chamar e usar no Storefront, dependendo do local e da funcionalidade necessária.
Os tamanhos são os seguintes:
- minúsculo: 50px de largura.
- polegar: 100px de largura.
- pequeno: 240px de largura.
- meio: 320px de largura.
- grande: 480px de largura.
- enorme: 640px de largura.
- Original: 1024px de largura
- 1080p: 1920px de largura (somente para imagens enviadas pelo “Personalizar meu layout atual”)
Se você precisar chamar uma imagem de produto da loja, precisaremos acessar o objeto "produto" localizado no modelo product.tpl ou em um loop de produto, como o grid de produto de uma categoria. Para entender melhor sobre os objetos do produto, visite product.tpl ou snipplets/product-grid.tpl
Por exemplo, podemos chamar a imagem principal de um produto da seguinte forma:
<img alt="{{ product.featured_image.alt }}" src="{{ product.featured_image | product_image_url('tiny')}}" >
Onde determinamos a tag <img> e usamos o objeto product.featured_image. E vamos determinar as seguintes propriedades para a imagem:
Alt: {{product.featured_image.alt}}
Src: {{product.featured_image | product_image_url ('tiny')}}
Neste caso, estamos chamando o tamanho tiny, mas podemos tranquilamente chamar o tamanho large da seguinte forma: <img alt = "{{product.featured_image.alt}}" src = "{{product.featured_image | product_image_url ('large') )}} ">
Mas, se você tiver que exibir uma imagem carregada na seção ‘Personalizar meu design atual’ na vitrine da loja, você precisará recorrer ao nome da setting (configuração). Por exemplo, se há uma setting para carregar imagens como as seguintes:
Image original = banner.jpg title = Cargar imagen (JPG, GIF, PNG) width = 600 height = 600
Vamos usar o seguinte código para exibi-la na loja:
{% if "banner.jpg" | has_custom_image %} <img src="{{ "banner.jpg" | static_url | settings_image_url('large') }}" > {% endif %}
Você pode consultar mais informações de como criar e admistrar as settings.txt em Config.
Tips
Verifique bem o tamanho da imagem que você chama para não carregar uma imagem maior do que a necessária. O desempenho da loja é melhor dessa forma.
Recomendamos o uso de Lazyload e srcset em todas as imagens que você usa para melhorar a velocidade de carregamento e a experiência do usuário. Veja todas as informações necessárias neste artigo: Imagens e desempenho
Checkout.css
IMPORTANTE! Não modifique a localização deste arquivo, pois a plataforma irá procurá-lo na pasta estática.
Este arquivo contém todos os estilos que personalizam o design de checkout. Pegue os parâmetros inseridos na ‘Personalização do design atual’, para aplicar as fontes e cores que a loja inteira possui.
O arquivo já possui todos os estilos existentes no checkout, portanto, não é necessário criar novos, exceto para um pseudo-elemento.
Para o checkout usar este style-sheet, ela deve ser ativada no Administrador Nuvem. Em "Configurações> Opções de check-out", a opção "Usar as cores do seu projeto no check-out" deve ser verificada na seção "Cores do check-out".