Neste vídeo, observaremos a anatomia do CSS (ou LESS) e JavaScript usado para estilizar o Componente de título principal do Experience Manager usando o Sistema de estilos, bem como a forma como esses estilos são aplicados ao HTML e ao DOM.
O pacote AEM fornecido (technical-review.sites.style-system-1.0.0.zip) instala o estilo de título de exemplo, políticas de exemplo para os componentes Contêiner de layout e Título do We.Retail, e uma página de exemplo.
technical-review.sites.style-system-1.0.0.zip
O seguinte é o LESS definição 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 deste trecho de código está o CSS deste LESS compila em.
/* 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 exposto acima LESS é compilado nativamente por Experience Manager para o CSS a seguir.
/* 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 a seguir coleta e injeta a data e 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 de jQuery é opcional, assim como as convenções de nomenclatura usadas.
O seguinte é o LESS definição 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);
});
Bom - Todos os elementos no componente são endereçáveis através 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 - A lista e os elementos da 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 poucos dados que precisem de desenvolvimento de back-end futuro para expô-los.
A implementação de alternadores de conteúdo editável pode ajudar a manter esse HTML enxuto, permitindo que os autores selecionem quais elementos de conteúdo serão gravados no HTML. As podem ser especialmente importantes ao gravar imagens no HTML que pode não ser usado para todos os estilos.
A exceção a essa regra é quando recursos caros, por exemplo, imagens, são expostos por padrão, já que as imagens de eventos ocultas pelo CSS são, nesse caso, buscadas desnecessariamente.
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 aplicados ao mesmo elemento, conforme especificado por BEM.
Em vez disso, devido a restrições do produto, a variável BLOCK--MODIFIER
é aplicado ao pai do BLOCK
elemento.
Todos os outros inquilinos de BEM deve ser alinhado com.
Use pré-processadores como MENOS (suportado pelo AEM nativamente) ou SCSS (requer um sistema de compilação personalizado) para permitir uma definição clara de CSS e reutilização.
Mantenha o peso/especificidade do seletor uniforme; isso ajuda a evitar e resolver conflitos em cascata de CSS difíceis de identificar.
Organize cada estilo em um arquivo distinto.
@imports
ou se o CSS bruto for necessário, por meio da inclusão de arquivos da Biblioteca de clientes HTML ou de sistemas personalizados de build de ativos front-end.Evite misturar muitos estilos complexos.
Sempre use classes CSS (seguindo a notação BEM) para definir regras CSS.
Evite estilizar o BLOCK--MODIFIER
diretamente, pois está anexada à Grade responsiva. Alterar a exibição desse elemento pode afetar a renderização e a funcionalidade da Grade Responsiva. Portanto, somente o estilo nesse nível quando a intenção for alterar o comportamento da Grade Responsiva.
Aplicar escopo de estilo usando BLOCK--MODIFIER
. A variável BLOCK__ELEMENT--MODIFIERS
pode ser usado no componente, mas como BLOCK
representa o componente, e o componente é estilizado, o estilo é "definido" e tem escopo definido por BLOCK--MODIFIER
.
A estrutura do seletor de CSS de exemplo deve ser a seguinte:
seletor de 1º nível BLOCO—MODIFICADOR |
Seletor de segundo nível BLOQUEAR |
seletor de 3º 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 | imagem .cmp | .cmp-image_caption | → | .cmp-image—hero imagem .cmp .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 definido pelo do componente principal BLOCK
. Ou seja, inicie o do componente aninhado BLOCK
no terceiro nível e os componentes aninhados do ELEMENT
está no quarto nível de seletor.
As práticas recomendadas definidas nesta seção referem-se ao "JavaScript de estilo" ou ao JavaScript especificamente destinado a manipular o componente para fins estilísticos, em vez de funcionais.
BLOCK--MODIFIERs
.BLOCK--MODIFIER BLOCK
e mostrá-lo quando todas as manipulações de DOM no JavaScript estiverem concluídas.