Neste vídeo vamos dar uma olhada na anatomia do CSS (ou LESS) e 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.
O pacote de AEM fornecido (technical-review.sites.style-system-1.0.0.zip) instala o estilo de título do exemplo, as políticas de amostra dos componentes do Contêiner e Título do layout We.Retail e uma página de exemplo.
technical-review.sites.style-system-1.0.0.zip
O seguinte é o LESS definição do 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 this 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 acima LESS é compilada nativamente por 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 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.
O seguinte é o LESS definição do 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);
});
Good - Todos os elementos no componente são endereçáveis via notação BEM:
<!-- Good practice -->
<div class="cmp-list">
<ul class="cmp-list__item-group">
<li class="cmp-list__item">...</li>
</ul>
</div>
Bad - Os elementos list e list só são endereçáveis por nome de 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, em que os autores são capazes de 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 são, nesse caso, buscadas desnecessariamente.
O Sistema de estilos faz uma pequena divergência técnica do BEM, na medida em que BLOCK
e BLOCK--MODIFIER
não são aplicadas ao mesmo elemento, como especificado por BEM.
Em vez disso, devido às restrições do produto, a variável BLOCK--MODIFIER
é aplicada ao pai da variável BLOCK
elemento.
Todos os outros locatários de BEM deve ser alinhado com .
Use pré-processadores como MENOS (suportado por AEM nativamente) ou SCSS (requer um sistema de build personalizado) para permitir definição clara de CSS e reutilização.
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.
@imports
ou se for necessário um CSS bruto, por meio da inclusão de arquivo da Biblioteca de clientes do HTML ou sistemas personalizados de criação de ativos front-end.Evite misturar vários estilos complexos.
Sempre use classes CSS (após a notação BEM) para definir regras CSS.
Evite colocar estilo no BLOCK--MODIFIER
diretamente, pois isso é 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.
Aplicar escopo de estilo usando BLOCK--MODIFIER
. O BLOCK__ELEMENT--MODIFIERS
pode ser usado no Componente, mas desde que o BLOCK
representa o Componente, e o Componente é o que tem o estilo, o Estilo é "definido" e o escopo é 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 componente pai BLOCK
. Ou, em outras palavras, inicie o componente aninhado BLOCK
no terceiro nível e no componente aninhado ELEMENT
está no quarto nível do seletor.
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.
BLOCK--MODIFIERs
.BLOCK--MODIFIER BLOCK
e mostre-a quando todas as manipulações de DOM no JavaScript forem concluídas.