Como entender o código do Sistema de estilos

Neste vídeo, vamos dar uma olhada na anatomia do CSS (ou LESS) e do JavaScript usados para criar um estilo no Componente de título principal do Experience Manager usando o Sistema de estilos, bem como em como esses estilos são aplicados ao HTML e DOM.

OBSERVAÇÃO

O Sistema de estilo do AEM foi introduzido com AEM 6.3 SP1 + Feature Pack 20593.

O vídeo supõe que o componente Título do We.Retail tenha sido atualizado para herdar de Componentes principais v2.0.0+.

Como entender o código do Sistema de estilos

O Pacote AEM fornecido (technical-review.sites.style-system-1.0.0.zip) instala o estilo de título de exemplo, as políticas de amostra para os componentes Contêiner e Título de layout We.Retail e uma página de exemplo.

technical-review.sites.style-system-1.0.0.zip

O CSS

Esta é a definição LESS para o estilo de exemplo encontrado em:

  • /apps/demo/sites/style-system/clientlib-example/components/titles/styles/example.less

Para aqueles que preferem CSS, abaixo desse trecho de código está o CSS no qual esse LESS é compilado.

/* LESS */
.cmp-title--example {
 .cmp-title {
  text-align: center;

  .cmp-title__text {
   color: #EB212E;
   font-weight: 600;
   font-size: 5rem;
   border-bottom: solid 1px #ddd;
   padding-bottom: 0;
   margin-bottom: .25rem
  }

  // Last Modified At element injected via JS
  .cmp-title__last-modified-at {
   color: #999;
   font-size: 1.5rem;
   font-style: italic;
   font-weight: 200;
  }
 }
}

O LESS acima é compilado nativamente pelo Experience Manager para o seguinte CSS.

/* CSS */
.cmp-title--example .cmp-title {
 text-align: center;
}

.cmp-title--example .cmp-title .cmp-title__text {
 color: #EB212E;
 font-weight: 600;
 font-size: 5rem;
 border-bottom: solid 1px #ddd;
 padding-bottom: 0;
 margin-bottom: 0.25rem;
}

.cmp-title--example .cmp-title .cmp-title__last-modified-at {
 color: #999;
 font-size: 1.5rem;
 font-style: italic;
 font-weight: 200;
}

O JavaScript

O JavaScript a seguir coleta e injeta a data e a hora da última modificação da página atual, abaixo do texto do título, quando o estilo Exemplo é aplicado ao componente Título .

O uso do jQuery é opcional, assim como as convenções de nomenclatura usadas.

Esta é a definição LESS para o estilo de exemplo encontrado em:

  • /apps/demo/sites/style-system/clientlib-example/components/titles/styles/js/title.js
/**
 * JavaScript supporting Styles may be re-used across multi Component Styles.
 *
 * For example:
 * Many styles may require the Components Image (provided via an <img> element) to be set as the background-image.
 * A single JavaScript function may be used to adjust the DOM for all styles that required this effect.
 *
 * JavaScript must react to the DOMNodeInserted event to handle style-switching in the Page Editor Authoring experience.
 * JavaScript must also run on DOM ready to handle the initial page load rendering (AEM Publish).
 * JavaScript must mark and check for elements as processed to avoid cyclic processing (ie. if the JavaScript inserts a DOM node of its own).
 */
jQuery(function ($) {
    "use strict;"

    moment.locale("en");

    /**
     * Method that injects p element, containing the current pages last modified date/time, under the title text.
     *
     * Similar to the CSS Style application, component HTML elements should be targeted via the BEM class names (as they define the stable API)
     * and targeting "raw" elements (ex. "li", "a") should be avoided.
     */
    function applyComponentStyles() {

        $(".cmp-title--example").not("[data-styles-title-last-modified-processed]").each(function () {
            var title = $(this).attr("data-styles-title-last-modified-processed", true),
                url = Granite.HTTP.getPath() + ".model.json";

            $.getJSON(url, function(data) {
                var dateObject = moment(data['lastModifiedDate']),
                    titleText = title.find('.cmp-title__text');

                titleText.after($("<p>").addClass("cmp-title__last-modified-at").text("Last modified " + dateObject.fromNow()));
            });
        });
    }

    // Handle DOM Ready event
    applyComponentStyles();

    // Apply Styles when a component is inserted into the DOM (ie. during Authoring)
    $(".responsivegrid").bind("DOMNodeInserted", applyComponentStyles);
});

Práticas recomendadas de desenvolvimento

Práticas recomendadas do HTML

  • O HTML (gerado via HTL) deve ser tão semântico estruturalmente quanto possível; evitar o agrupamento/aninhamento desnecessário de elementos.
  • Os elementos HTML devem ser endereçáveis por meio de classes CSS de estilo BEM.

Bom - Todos os elementos no componente são endereçáveis por meio da notação BEM:

<!-- Good practice -->
<div class="cmp-list">
    <ul class="cmp-list__item-group">
        <li class="cmp-list__item">...</li>
    </ul>
</div>

Ruim - Os elementos de lista e lista são endereçáveis somente pelo nome do elemento:

<!-- Bad practice -->
<div class="cmp-list">
    <ul>
        <li>...</li>
    </ul>
</div>
  • É melhor expor mais dados e ocultá-los do que expor muito poucos dados que exijam o desenvolvimento de back-end futuro para expô-los.

    • A implementação de alternâncias de conteúdo com autor pode ajudar a manter esse HTML limpo, em que os autores podem selecionar quais elementos de conteúdo são gravados no HTML. A pode ser especialmente importante ao gravar imagens no HTML que podem não ser usadas para todos os estilos.

    • A exceção a essa regra é quando recursos caros, por exemplo, imagens, são expostos por padrão, pois imagens de evento ocultas por CSS serão, nesse caso, buscadas desnecessariamente.

      • Os componentes de imagem modernos geralmente usam o JavaScript para selecionar e carregar a imagem mais apropriada para o caso de uso (visor).

Práticas recomendadas de CSS

OBSERVAÇÃO

O Sistema de estilos faz uma pequena divergência técnica de BEM, na medida em que BLOCK e BLOCK--MODIFIER não são aplicadas ao mesmo elemento, conforme especificado por BEM.

Em vez disso, devido a restrições de produto, BLOCK--MODIFIER é aplicado ao pai do elemento BLOCK.

Todos os outros locatários de BEM devem ser alinhados com.

  • Use pré-processadores como LESS (suportado pelo AEM nativamente) ou SCSS (requer sistema de compilação personalizado) para permitir uma definição clara de CSS e reutilizabilidade.

  • Manter uniforme o peso/a especificidade do seletor; Isso ajuda a evitar e resolver conflitos em cascata de CSS difíceis de identificar.

  • Organize cada estilo em um arquivo discreto.

    • Esses arquivos podem ser combinados usando LESS/SCSS @imports ou se CSS bruto for necessário, por meio da inclusão de arquivo da Biblioteca de clientes HTML ou sistemas personalizados de criação de ativos front-end.
  • Evite misturar vários estilos complexos.

    • Quanto mais estilos puderem ser aplicados em um único momento a um componente, maior será a variedade de permutas. Isso pode se tornar difícil de manter/QA/garantir o alinhamento da marca.
  • Sempre use classes CSS (após a notação BEM) para definir regras CSS.

    • Se a seleção de elementos sem classes CSS (ou seja, elementos nus) for absolutamente necessária, mova-os para cima na definição de CSS para deixar claro que eles têm uma especificidade menor do que qualquer colisão com elementos desse tipo que tenham classes CSS selecionáveis.
  • Evite estilizar o BLOCK--MODIFIER diretamente, pois ele está anexado à Grade Responsiva. Alterar a exibição desse elemento pode afetar a renderização e a funcionalidade da Grade Responsiva, portanto, estime apenas nesse nível quando a intenção for alterar o comportamento da Grade Responsiva.

  • Aplique o escopo do estilo usando BLOCK--MODIFIER. O BLOCK__ELEMENT--MODIFIERS pode ser usado no Componente, mas como o BLOCK representa o Componente, e o Componente é o que tem o estilo, o Estilo é "definido" e com escopo via BLOCK--MODIFIER.

Exemplo de estrutura do seletor de CSS deve ser o seguinte:

Seletor de primeiro nível

BLOCO—MODIFICADOR

Seletor de segundo nível

BLOCO

Seletor de terceiro nível

BLOCK_ELEMENT

Seletor de CSS efetivo
.cmp-list — escuro .cmp-list .cmp-list_item

.cmp-list — escuro

.cmp-list

.cmp-list__item {

cor: Azul;

}

.cmp-image—hero .cmp-image .cmp-image__caption

.cmp-image—hero

.cmp-image

.cmp-image__caption {

cor: vermelho;

}

No caso de componentes aninhados, a profundidade do seletor de CSS para esses elementos de Componentes aninhados excederá o seletor de terceiro nível. Repita o mesmo padrão para o componente aninhado, mas com escopo pelo BLOCK do Componente pai. Ou, em outras palavras, inicie o BLOCK do componente aninhado no terceiro nível e o ELEMENT do Componente aninhado estará no quarto nível do seletor.

Práticas recomendadas do JavaScript

As práticas recomendadas definidas nesta seção pertencem ao "style-JavaScript" ou ao JavaScript especificamente destinado a manipular o componente para fins estilísticos, em vez de funcionais.

  • O Style-JavaScript deve ser usado criteriosamente e é um caso de uso minoritário.
  • O Style-JavaScript deve ser usado principalmente para manipular o DOM do componente para oferecer suporte a estilo por CSS.
  • Reavalie o uso do Javascript se os componentes forem exibidos várias vezes em uma página e entenda o custo computacional/de redesenho.
  • Reavalie o uso do Javascript se ele receber novos dados/conteúdo de forma assíncrona (via AJAX) quando o componente puder aparecer várias vezes em uma página.
  • Lida com as experiências de publicação e criação.
  • Reutilize style-Javascript quando possível.
    • Por exemplo, se vários estilos de um Componente exigirem que sua imagem seja movida para uma imagem de plano de fundo, o JavaScript de estilo poderá ser implementado uma vez e anexado a vários BLOCK--MODIFIERs.
  • Separe o JavaScript de estilo do JavaScript funcional quando possível.
  • Avalie o custo do JavaScript em vez de manifestar essas alterações DOM no HTML diretamente via HTL.
    • Quando um componente que usa o estilo-JavaScript requer modificação do lado do servidor, avalie se a manipulação do JavaScript pode ser trazida para o momento e quais efeitos/ramificações são para o desempenho e a capacidade de suporte do componente.

Considerações de desempenho

  • O Style-JavaScript deve ser mantido leve e limpo.
  • Para evitar cintilação e redesenhações desnecessárias, oculte inicialmente o componente por BLOCK--MODIFIER BLOCK e mostre-o quando todas as manipulações DOM no JavaScript estiverem concluídas.
  • O desempenho das manipulações style-JavaScript é semelhante aos plug-ins básicos do jQuery que são anexados e modificados em DOMReady.
  • Verifique se as solicitações estão gzipadas e se o CSS e o JavaScript estão minificados.

Recursos adicionais

Nesta página

Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now