Manipulação de pseudo-elements com JavaScript

Felquis G
3 min readFeb 7, 2017

--

Isso parece ser algo muito óbvio, mas quando eu precisei manipular um pseudo-elemento via JavaScript, eu me dei conta que não era tão simples assim.

Para começar, não existe uma maneira de selecionar um pseudo-elemento no JavaScript como fazemos com elementos normais

A missão aqui é por exemplo, selecionar o body:before e mudar a propriedade color dele ou o que tiver direito.

CSS Object Model

A melhor forma que encontrei de alterar um pseudo-elemento foi procurando pelo seletor que desejo manipular nas folhas de estilho da página.

No browser temos um document.styleSheetsque contem uma lista de folhas de estilos da página, tudo o que eu faço é encontrar em qual dessas folhas de estilo está o seletor que eu quero, e altero a propriedade style dele e essa alteração será refletida na página.

const bodyBefore = document.styleSheets[1].cssRules[0]bodyBefore.style.fontSize = '2em'
bodyBefore.style.margin = '1em'
bodyBefore.style.color = 'blue'

codepen: http://codepen.io/felquis/pen/zNLEaW?editors=0110#0

Para mexer com o CSSOM, em folhas de estilo muito grandes, é necessário fazer alguns filters e maps e flatMaps, aprendi isso fazendo este projeto, recomendo a leitura do MDN sobre document.styleSheets

Abaixo vou mencionar alguns experimentos que fiz enquanto buscava fazer exatamente o descrito acima.

Como alterar a propriedade content de um pseudo-elemento

Levando em consideração que não temos como alterar propriedades do CSS de um pseudo-elemento, temos um workaround bem eficiente e que funciona bem, para isso leve em consideração o HTML

<span>Algo está acontecendo</span>

O CSS

span {
position: relative;
display: block;
padding: 20px 0 0 0;
}
span:before {
content: attr(data-content);
position: absolute;
top: 0;
left: 0;
color: gray;
}

E o JS

var span = document.querySelector('span');span.dataset.content = 'Muda valor da propriedade, e isso reflete no pseudo-elemento';

Okay, no CSS repare que a propriedade content está usando a expressão attr() isso significa que qualquer valor que tiver no atributo data-content do elemento selecionado, será adicionado a propriedade content do pseudo-elemento.

Também podemos usar o método setAttribute para alterar o valor de uma propriedade data-content, assim:

var span = document.querySelector('span');span.setAttribute('data-content', 'Muda valor da propriedade, e isso reflete no pseudo-elemento');

Veja o demo no Codepen http://codepen.io/felquis/pen/wHAxe

Espero que esta dica tenha sido útil :) Por algum motivo, a galera das especificações não deram a minima para a manipulação de pseudo-elementos, seria fantástico se pudéssemos fazer algo assim

document.querySelector('span:after').style.content = 'Altera a propriedade content';

Infelizmente isso não é possível, se você saber o porque, me conte!

Como pegar uma propriedade do CSS de um pseudo-elemento

Bom, não é possível alterar propriedades do CSS de pseudo-elementos, mas, é possível saber o valor de uma propriedade de um pseudo-elemento com o getComputedStyle

O getComputedStyle retorna todos as propriedades do CSS que foram usadas para renderizar um elemento na tela, e seus valores são imutáveis, read only.

Para usar este método basta passar um elemento, e o segundo parâmetro é opcional e representa um pseudo-elemento :after ou :before.

Assim como no nosso exemplo acima, se quisermos saber o que tem no atributo content basta usar o seguinte

var styles = window.getComputedStyle(
document.querySelector('span'),
':before'
);

Este método fantástico retorna pra gente o que eles chamam de CSSStyleDeclaration que nada mais é do que um objeto em que cada propriedade é uma regra do CSS.

Então, veja isso:

var styles = window.getComputedStyle(
document.querySelector('span'),
':before'
)
// Agora o que tem na propriedade content?
console.log( styles.content ) // Retorna a propriedade content
// O que tem na propriedade color?
console.log( styles.color )
// Também pode ser usado um método bonito que tem nesse tal de CSSStyleDeclaration
console.log( styles.getPropertyValue('color') )

Você pode ver o que você quiser.

Bom, talvez você não tenha encontrado a utilidade de pegar os valores computados, mas recentemente vi uma galera testando se um browser suporta CSS Animations em pseudo-elementos usando getComputedStyle, leia o artigo completo aqui

Basicamente, o teste é colocar uma animação super rápida em um elemento coisa de 0.001s animando a propriedade color de red para green, o computedStyle retorna como o elemento está renderizado na tela, ou seja, se a animação aconteceu a propriedade color deveria estar com o RGB de green, isso significa que o browser suporta animações em pseudo-elementos e se estiver red significa que o browser ignorou a animation e não oferece suporte a animations em pseudo-elementos.

Lembre-se o que são pseudo-elementos

Quando se fala em pseudo-elemento a primeira (ou primeira e segunda) coisa que vem na cabeça é :after e :before pois então, faça seu dever de casa e aprenda os demais pseudo-elementos disponíveis no CSS.

Todos eles possuem recursos limitados no CSS.

Acho que já passei o que queria passar, então é isso ai galera.

--

--