¿Puedo tener múltiples: antes de pseudo-elementos para el mismo elemento?

116

¿Es posible tener múltiples :beforepseudos para el mismo elemento?

.circle:before {
    content: "\25CF";
    font-size: 19px;
}
.now:before{
    content: "Now";
    font-size: 19px;
    color: black;
}

Estoy tratando de aplicar los estilos anteriores al mismo elemento usando jQuery, pero solo se aplica el más reciente, nunca ambos.

ChrisOdney
fuente

Respuestas:

94

En CSS2.1, un elemento solo puede tener como máximo uno de cualquier tipo de pseudoelemento en cualquier momento. (Esto significa que un elemento puede tener tanto un elemento :beforecomo un :afterpseudoelemento, simplemente no puede tener más de uno de cada tipo).

Como resultado, cuando tiene varias :beforereglas que coinciden con el mismo elemento, todas se aplicarán en cascada y se aplicarán a un solo :beforepseudoelemento, como con un elemento normal. En su ejemplo, el resultado final se ve así:

.circle.now:before {
    content: "Now";
    font-size: 19px;
    color: black;
}

Como puede ver, solo la contentdeclaración que tiene la prioridad más alta (como se mencionó, la que viene en último lugar) entrará en vigencia; el resto de las declaraciones se descartan, como es el caso con cualquier otra propiedad CSS.

Este comportamiento se describe en la sección Selectores de CSS2.1 :

Los pseudoelementos se comportan como elementos reales en CSS con las excepciones que se describen a continuación y en otros lugares.

Esto implica que los selectores con pseudoelementos funcionan como selectores para elementos normales. También significa que la cascada debería funcionar de la misma manera. Curiosamente, CSS2.1 parece ser la única referencia; ni css3-selectors ni css3-cascade mencionan esto en absoluto, y queda por ver si se aclarará en una especificación futura.

Si un elemento puede hacer coincidir más de un selector con el mismo pseudoelemento y desea que todos se apliquen de alguna manera, deberá crear reglas CSS adicionales con selectores combinados para poder especificar exactamente lo que debe hacer el navegador en esos casos. No puedo proporcionar un ejemplo completo que incluya la contentpropiedad aquí, ya que no está claro, por ejemplo, si el símbolo o el texto deben ir primero. Pero el selector que necesita para esta regla combinada es .circle.now:beforeo .now.circle:before- el selector que elija es preferencia personal, ya que ambos selectores son equivalentes, es solo el valor de la contentpropiedad lo que deberá definir usted mismo.

Si aún necesita un ejemplo concreto, vea mi respuesta a esta pregunta similar .

La especificación de contenido css3 heredado contiene una sección sobre la inserción de elementos múltiples ::beforey ::afterpseudoelementos utilizando una notación que es compatible con la cascada CSS2.1, pero tenga en cuenta que ese documento en particular está obsoleto; no se ha actualizado desde 2003 y nadie lo ha hecho. implementó esa característica en la última década. La buena noticia es que el documento abandonado se está reescribiendo activamente bajo la apariencia de css-content-3 y css-pseudo-4 . La mala noticia es que la característica de múltiples pseudoelementos no se encuentra en ninguna de las dos especificaciones, presumiblemente debido, nuevamente, a la falta de interés del implementador.

BoltClock
fuente
12
En el caso dado, si un elemento pertenece tanto a la clase circlecomo a la clase now, ambas reglas se aplican al :beforepseudo-elemento del elemento, pero el CSS normal implica que solo una de las contentconfiguraciones puede tener efecto (por las reglas normales en cascada). El caso es que contentno se acumula.
Jukka K. Korpela
Resulta que esta pregunta que respondí varios meses después es un duplicado de esta. Desde entonces, fusioné la mayor parte de la información de la otra respuesta, que básicamente amplía todo lo que @Jukka ha dicho anteriormente, en esta, ya que está recibiendo mucho más tráfico, además de ser el primero.
BoltClock
1
Después de 13 años, el borrador css-content-3 finalmente se ha actualizado . La sección de pseudo-elementos definitivamente se ha eliminado a favor de css-pseudo-4, que no permite múltiples ::beforeni ::afterpseudo-elementos.
Oriol
@Oriol: 12 años, en realidad. el FPWD de css-pseudo-4 se introdujo el año pasado, momento en el que css-content-3 ya se había actualizado para apuntar a la nueva especificación.
BoltClock
@BoltClock El borrador del editor css-content-3 en drafts.csswg.org se actualizó hace algún tiempo, pero el borrador de trabajo en w3.org seguía siendo el de 2003 hasta hace poco. Todavía tenía algunas esperanzas ...
Oriol
31

Si su elemento principal tiene algunos elementos secundarios o texto, puede utilizarlo.

Coloque su elemento principal relativo (o absoluto / fijo) y use ambos: antes y: después posicionado absoluto (en mi situación tenía que ser absoluto, no sé el suyo).

Ahora, si desea un pseudoelemento más, adjunte un absoluto: antes a uno de los hijos del elemento principal (si solo tiene texto, colóquelo en un intervalo, ahora tiene un elemento), que no es relativo / absoluto / fijo .

Este elemento comenzará a actuar como si su dueño fuera su elemento principal.

HTML

<div class="circle">
    <span>Some text</span>
</div>

CSS

.circle {
    position: relative; /* or absolute/fixed */
}

.circle:before {
    position: absolute;
    content: "";
    /* more styles: width, height, etc */
}

.circle:after {
    position: absolute;
    content: "";
    /* more styles: width, height, etc */
}

.circle span {
    /* not relative/absolute/fixed */
}

.circle span:before {
    position: absolute;
    content: "";
    /* more styles: width, height, etc */
}
HydraOrc
fuente
2
Si bien la respuesta seleccionada es precisa, esta fue una solución viable para mi caso. ¡Pude simular tener múltiples elementos psuedo sin necesidad de agregar más nodos al DOM!
matt.kauffman23
@ matt.kauffman23 entonces, ¿podrías decirnos cómo hiciste la simulación?
BbIKTOP
1
@BbIKTOP lo siento, acabo de ver tu comentario. En mi caso, estaba trabajando en un modal que siempre tenía hijos, así que terminé con algo como:.modal:first-child:before { …
matt.kauffman 23 de
@ matt.kauffman23 Para recordar un detalle como este después de más de 6 años, ¡tienes un gran recuerdo!
ChrisOdney
1

Resolví esto usando:

.element:before {
    font-family: "Font Awesome 5 Free" , "CircularStd";
    content: "\f017" " Date";
}

Usando la familia de fuentes "font awesome 5 free" para el ícono, y luego, tenemos que especificar la fuente que estamos usando nuevamente porque si no lo hacemos, el navegador usará la fuente predeterminada (times new roman o algo así como esta).

Keko Perera
fuente