¿Puede una clase CSS heredar una o más clases?

736

Me siento tonto por haber sido un programador web durante tanto tiempo y no saber la respuesta a esta pregunta, de hecho espero que sea posible y simplemente no sabía más de lo que creo que es la respuesta (que es que no es posible) .

Mi pregunta es si es posible hacer una clase CSS que "herede" de otra clase CSS (o más de una).

Por ejemplo, digamos que teníamos:

.something { display:inline }
.else      { background:red }

Lo que me gustaría hacer es algo como esto:

.composite 
{
   .something;
   .else
}

donde la clase ".composite" se mostraría en línea y tendría un fondo rojo

Joel Martinez
fuente
3
piense más en cascada que en herencia, no se aplica aquí
blu

Respuestas:

427

Hay herramientas como LESS , que le permiten componer CSS en un nivel más alto de abstracción similar a lo que describe.

Menos llama a estos "Mixins"

En vez de

/* CSS */
#header {
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
}

#footer {
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
}

Tu puedes decir

/* LESS */
.rounded_corners {
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
}

#header {
  .rounded_corners;
}

#footer {
  .rounded_corners;
}
Larsenal
fuente
37
wow, LESS es más o menos exactamente lo que estoy buscando ... es una pena que no sea compatible de forma nativa, y que esté escrito en Ruby (estoy usando ASP.NET MVC)
Joel Martinez
1
Sí, también estoy en el mundo ASP.NET, así que no lo he movido a mi flujo de trabajo de producción.
Larsenal
Menos es hermoso y tentador ... pero no he tenido mucho éxito al usarlo con CSSEdit en el mismo flujo de trabajo, por lo que aún no lo he adoptado totalmente.
Ryan Florence
1
Sí, MENOS es bastante dulce, ¿no? De hecho, he estado trabajando en un puerto .NET aquí: nlesscss.codeplex.com .
Owen el
77
en caso de que llegue a esto a través de google: el puerto .Net ya está aquí
Eonasdan
310

Puede agregar varias clases a un único elemento DOM, por ejemplo

<div class="firstClass secondClass thirdclass fourthclass"></div>

Las reglas dadas en clases posteriores (o que son más específicas) se anulan. Así fourthclassque en ese ejemplo prevalece el tipo de.

La herencia no es parte del estándar CSS.

Matt Bridges
fuente
12
¿sabe si qué clase prevalece, las últimas o las primeras y es seguro el comportamiento entre navegadores? Digamos que tenemos .firstClass {font-size:12px;} .secondClass {font-size:20px;}entonces font-sizeserá 12pxo o ¿ 20pxes seguro este navegador cruzado?
Marco Demaio
27
La regla con la mayor especificidad en el selector ganará. Se aplican reglas de especificidad estándar; en su ejemplo, dado que "primero" y "segundo" tienen la misma especificidad, la regla declarada más adelante en el CSS ganará.
Matt Bridges
19
Me gusta la idea de usar CSS puro (en lugar de MENOS) para resolver este problema.
Alex
8
También me gusta la idea de no escribir varias clases varias veces, que es O (n ^ 2) trabajo :)
Secreto
3
¿Qué sucede si estoy usando una biblioteca de terceros y quiero modificar el diseño / HTML que proporciona, pero no puedo cambiar los archivos CSS incorporados en esa biblioteca? Allí necesitaría algún tipo de herencia en las clases CSS.
Shivam
112

Sí, pero no exactamente con esa sintaxis.

.composite,
.something { display:inline }

.composite,
.else      { background:red }
mlouro
fuente
77
Esto apesta, pero me alegro de que al menos tengamos esto.
Pacerier
3
¿Por qué apesta? parece muy bueno No puedo entender la diferencia entre el símbolo de coma y la solución less.js.
Anterior
21
Porque si las clases .something y .else están en archivos diferentes y no puedes modificarlas, entonces estás atascado.
Alexandre Mélard
8
Esta fue la respuesta correcta porque respondió la pregunta usando sintaxis CSS pura. Sin embargo, la respuesta menos es bueno saber.
raddevus
1
Esta debería ser la respuesta exceptuada.
eaglei22
66

Mantenga sus atributos comunes juntos y asigne atributos específicos (o anular) nuevamente.

/*  ------------------------------------------------------------------------------ */   
/*  Headings */ 
/*  ------------------------------------------------------------------------------ */   
h1, h2, h3, h4
{
    font-family         : myfind-bold;
    color               : #4C4C4C;
    display:inline-block;
    width:900px;
    text-align:left;
    background-image: linear-gradient(0,   #F4F4F4, #FEFEFE);/* IE6 & IE7 */
}

h1  
{
    font-size           : 300%;
    padding             : 45px 40px 45px 0px;
}

h2
{
    font-size           : 200%;
    padding             : 30px 25px 30px 0px;
}
user2990362
fuente
2
Esto está muy cerca de una solución ideal, espero que la gente no lo descarte solo porque obtuvo pocos votos. De hecho, uno de los problemas más desafiantes sobre la "herencia CSS" es que generalmente obtienes un software web enorme ya hecho (por ejemplo, un comercio electrónico o un software famoso de PHP para blogs) y emplean código PHP que ganó de forma nativa ' No agregue varias clases a los elementos HTML que salen. Esto lo obliga a dar vueltas y meterse con el código fuente (perder cambios si actualiza más adelante) para que genere esas clases adicionales. Con este enfoque, en cambio, ¡solo edita el archivo CSS!
Dario Fumagalli
3
Esto era exactamente lo que estaba buscando. ¿No vale nada que este mismo enfoque funcione con los selectores CSS? En lugar de especificar h1, h2, etc, podría especificar.selector1, .selector2, .etc
JeffryHouser
Quería comentar que este es precisamente el enfoque utilizado por w3 en su hoja de estilo html predeterminada recomendada: [w3 CSS2]: w3.org/TR/CSS2/sample.html . También estoy tratando de comprender cómo organizar el código CSS, y parece que el paradigma está invertido en comparación con la herencia orientada a objetos típica: se usan clases (o, en general, selectores) para especificar qué elementos heredan qué atributos, pero usted hereda los atributos (al menos, así es como la jerarquía puede existir lógicamente más fácilmente), luego anula los atributos en los selectores más específicos cuando sea necesario.
Nathan Chappell
51

Un elemento puede tomar múltiples clases:

.classOne { font-weight: bold; }
.classTwo { font-famiy:  verdana; }

<div class="classOne classTwo">
  <p>I'm bold and verdana.</p>
</div>

Y eso es lo más cerca que estarás desafortunadamente. Me encantaría ver esta característica, junto con los alias de clase algún día.

Sampson
fuente
45

No, no puedes hacer algo como

.composite 
{
   .something;
   .else
}

Estos no son nombres de "clase" en el sentido OO. .somethingy.else son solo selectores nada más.

Pero puedes especificar dos clases en un elemento

<div class="something else">...</div>

o podrías buscar otra forma de herencia

.foo {
  background-color: white;
  color: black;
}

.bar {
  background-color: inherit;
  color: inherit;
  font-weight: normal;
}
<div class="foo">
  <p class="bar">Hello, world</p>
</div>

Donde los párrafos backgroundcolor y color se heredan de la configuración en el div adjunto que tiene el .fooestilo. Puede que tenga que verificar la especificación exacta del W3C. inheritde todos modos es el valor predeterminado para la mayoría de las propiedades, pero no para todas.

estar nervioso
fuente
1
sí, esta (primera parte) era lo que esperaba cuando escuché por primera vez sobre CSS en el siglo XX ... y todavía no lo tenemos, están quemando el rendimiento en algunas cosas dinámicas, mientras que esto puede estar compuesto estático justo antes de que se aplique el CSS y reemplaza la necesidad de variables ("variables" estáticas)
neu-rah
30

Me encontré con este mismo problema y terminé usando una solución JQuery para que pareciera que una clase puede heredar otras clases.

<script>
    $(function(){
            $(".composite").addClass("something else");
        });
</script>

Esto encontrará todos los elementos con la clase "compuesto" y agregará las clases "algo" y "otra cosa" a los elementos. Entonces algo así <div class="composite">...</div>terminará así:
<div class="composite something else">...</div>

DHoover
fuente
1
El problema con esta solución es que se aplica a todos los controles existentes, si crea el control después de esta llamada, no tendrá la nueva clase.
LuisEduardoSP
27

La forma SCSS para el ejemplo dado sería algo como:

.something {
  display: inline
}
.else {
  background: red
}

.composite {
  @extend .something;
  @extend .else;
}

Más información, consulte los conceptos básicos de Sass

Alter Lagos
fuente
¿Cuál es el valor agregado en comparación con esto? .composite,.something { display:inline }y.composite,.else { background:red }
Pavel Gatnar
2
@PavelGatnar Puede reutilizar las definiciones de .somethingy .elseen otras definiciones CSS.
Alter Lagos
16

Lo mejor que puedes hacer es esto

CSS

.car {
  font-weight: bold;
}
.benz {
  background-color: blue;
}
.toyota {
  background-color: white;
}

HTML

<div class="car benz">
  <p>I'm bold and blue.</p>
</div>
<div class="car toyota">
  <p>I'm bold and white.</p>
</div>
electricbah
fuente
12

No olvides:

div.something.else {

    // will only style a div with both, not just one or the other

}
Ryan Florence
fuente
1
No lo estoy buscando, pero esto fue constructivo para mí n__n
AgelessEssence
7

En archivo Css:

p.Title 
{
  font-family: Arial;
  font-size: 16px;
}

p.SubTitle p.Title
{
   font-size: 12px;
}
pedrofernandes
fuente
2
Entonces, ¿cuál será el resultado font-size?
abatishchev
El tamaño de fuente sería 12px para "p.Title" porque se define después del primero en el archivo. anula el primer tamaño de fuente.
YWE
@YWE: ¿Eso significa que las declaraciones deberían ser al revés en comparación con lo que está escrito en esta respuesta (al menos si queremos que el ejemplo sea ilustrativo)? Si prevalece el último definido, font-size: 16pxnunca puede surtir efecto, ¿verdad?
O Mapper
@ORMapper: normalmente, lo que sucede es que la primera declaración está en un archivo css común, que es compartido por varias páginas. Luego, la segunda declaración está en un segundo archivo css, usado solo en ciertas páginas. E importado después del archivo css común. Entonces esas páginas usan el valor "visto por última vez" de 12px.
ToolmakerSteve
7

Me doy cuenta de que esta pregunta ahora es muy antigua pero, ¡aquí no pasa nada!

Si la intención es agregar una sola clase que implique las propiedades de varias clases, como solución nativa, recomendaría usar JavaScript / jQuery (jQuery realmente no es necesario, pero ciertamente es útil)

Si tiene, por ejemplo, .umbrellaClassque "hereda" de .baseClass1y .baseClass2podría tener listo JavaScript que se activa.

$(".umbrellaClass").addClass("baseClass1");
$(".umbrellaClass").addClass("baseClass2");

Ahora todos los elementos de .umbrellaClasstendrán todas las propiedades de ambos .baseClasss. Tenga en cuenta que, como la herencia OOP,.umbrellaClass puede o no tener sus propias propiedades.

La única advertencia aquí es considerar si se están creando dinámicamente elementos que no existirán cuando se active este código, pero también hay formas simples de evitarlo.

Sin embargo, apesta css no tiene herencia nativa.

John Carrell
fuente
1
Este enfoque ya ha sido sugerido en la respuesta de @ DHoover de 2013.
Bryan
6

Momento perfecto : pasé de esta pregunta a mi correo electrónico, para encontrar un artículo sobre Less , una biblioteca de Ruby que, entre otras cosas, hace esto:

Como se super ve igual footer, pero con una fuente diferente, usaré la técnica de inclusión de clase de Less (lo llaman mixin) para decirle que incluya estas declaraciones también:

#super {
  #footer;
  font-family: cursive;
}
RichieHindle
fuente
Justo cuando pensaba que MENOS no podía sorprenderme más ... No tenía idea de que podría importar el formato de otro bloque como este. Gran consejo
Daniel Rippstein
4

Desafortunadamente, CSS no proporciona 'herencia' en la forma en que lo hacen los lenguajes de programación como C ++, C # o Java. No puede declarar una clase CSS y luego extenderla con otra clase CSS.

Sin embargo, puede aplicar más de una clase a una etiqueta en su marcado ... en cuyo caso hay un conjunto sofisticado de reglas que determinan qué estilos reales aplicará el navegador.

<span class="styleA styleB"> ... </span>

CSS buscará todos los estilos que se pueden aplicar en función de su marcado, y combinará los estilos CSS de esas múltiples reglas juntas.

Por lo general, los estilos se fusionan, pero cuando surgen conflictos, el estilo declarado más tarde generalmente ganará (a menos que el atributo! Important esté especificado en uno de los estilos, en cuyo caso eso gana). Además, los estilos aplicados directamente a un elemento HTML tienen prioridad sobre los estilos de clase CSS.

LBushkin
fuente
Su respuesta vino como primer resultado en google para mí y fue útil. Dicho esto, tengo un consejo para usted: si está ofreciendo una solución, es mejor evitar comenzar las oraciones negativamente (Desafortunadamente, CSS no proporciona herencia ...) Sé que cualquiera con la paciencia adecuada leería para descubrir su buena solución. pero a veces las personas se están quedando sin paciencia y pueden llegar a la conclusión de que lo que están tratando de hacer es imposible. Para tener la mejor oportunidad de ayudar a otros, puede comenzar con algo como "Si bien CSS no tiene herencia, puede lograr lo que necesita por ..."
egmfrs
4

También hay SASS, que puedes encontrar en http://sass-lang.com/ . Hay una etiqueta @extend, así como un sistema de tipo mix-in. (Rubí)

Es una especie de competidor MENOS.

chug2k
fuente
4

Eso no es posible en CSS.

Lo único compatible con CSS es ser más específico que otra regla:

span { display:inline }
span.myclass { background: red }

Un lapso con la clase "myclass" tendrá ambas propiedades.

Otra forma es especificando dos clases:

<div class="something else">...</div>

El estilo de "else" anulará (o agregará) el estilo de "algo"

Philippe Leybaert
fuente
Para todos los estilos en 1 archivo hay una solución similar a la herencia en CSS, vea mi publicación.
Pavel Gatnar
3

Puede aplicar más de una clase CSS a un elemento mediante algo como esta clase = "algo más"

Pete
fuente
3

Como han dicho otros, puede agregar varias clases a un elemento.

Pero ese no es realmente el punto. Recibo tu pregunta sobre la herencia. El punto real es que la herencia en CSS se hace no a través de clases, sino a través de las jerarquías de elementos. Por lo tanto, para modelar rasgos heredados, debe aplicarlos a diferentes niveles de elementos en el DOM.

Assaf Lavie
fuente
Es mejor crear definiciones CSS de herencia en lugar de usar toda la cadena de clases de composición, vea mi publicación.
Pavel Gatnar
2

Estaba buscando eso como loco también y lo descubrí probando cosas diferentes: P ... Bueno, puedes hacerlo así:

composite.something, composite.else
{
    blblalba
}

De repente funcionó para mí :)

BiBi
fuente
2

En circunstancias específicas, puede hacer una herencia "blanda":

.composite
{
display:inherit;
background:inherit;
}

.something { display:inline }
.else      { background:red }

Esto solo funciona si está agregando la clase .composite a un elemento hijo. Es una herencia "blanda" porque los valores no especificados en .composite no se heredan obviamente. Tenga en cuenta que todavía sería menos caracteres simplemente escribir "en línea" y "rojo" en lugar de "heredar".

Aquí hay una lista de propiedades y si lo hacen automáticamente o no: https://www.w3.org/TR/CSS21/propidx.html

hydrix
fuente
2

Si bien la herencia directa no es posible.

Es posible usar una clase (o id) para una etiqueta primaria y luego usar combinadores CSS para alterar el comportamiento de la etiqueta secundaria desde su jerarquía.

p.test{background-color:rgba(55,55,55,0.1);}
p.test > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span > span > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span > span > span > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span > span > span > span > span > span{background-color:rgba(55,55,55,0.1);}
<p class="test"><span>One <span>possible <span>solution <span>is <span>using <span>multiple <span>nested <span>tags</span></span></span></span></span></span></span></span></p>

No sugeriría usar tantos tramos como el ejemplo, sin embargo, es solo una prueba de concepto. Todavía hay muchos errores que pueden surgir al intentar aplicar CSS de esta manera. (Por ejemplo, alterar los tipos de decoración de texto).

Stryderunknown
fuente
2

Less y Sass son preprocesadores de CSS que amplían el lenguaje CSS de formas valiosas. Solo una de las muchas mejoras que ofrecen es la opción que está buscando. Hay algunas respuestas muy buenas con Less y agregaré la solución Sass.

Sass tiene una opción de extensión que permite que una clase se extienda completamente a otra. Más sobre extender puedes leer en este artículo

Nesha Zoric
fuente
1

CSS realmente no hace lo que estás pidiendo. Si desea escribir reglas con esa idea compuesta en mente, puede consultar la brújula . Es un marco de hoja de estilo que se parece al Menor ya mencionado.

Te permite hacer mixins y todo ese buen negocio.

Zack The Human
fuente
Agregando más detalles a lo anterior, Compass aka Sass lo hace a través de Extend, PlaceHolders Mixins vs Extend , información más detallada sobre PlaceHolders
Abhijeet
1

Para aquellos que no están satisfechos con las publicaciones mencionadas (excelentes), puede usar sus habilidades de programación para hacer una variable (PHP o lo que sea) y hacer que almacene los nombres de múltiples clases.

Ese es el mejor truco que se me ocurrió.

<style>
.red { color: red; }
.bold { font-weight: bold; }
</style>

<? define('DANGERTEXT','red bold'); ?>

Luego aplique la variable global al elemento que desee en lugar de los nombres de clase en sí

<span class="<?=DANGERTEXT?>"> Le Champion est Ici </span>
Shakir
fuente
1

No piense en las clases css como clases orientadas a objetos, piense en ellas como una mera herramienta entre otros selectores para especificar qué clases de atributos se diseñan para un elemento html. Piense en todo entre las llaves como la clase de atributo , y los selectores en el lado izquierdo le dicen a los elementos que seleccionan para heredar atributos de la clase de atributo . Ejemplo:

.foo, .bar { font-weight : bold; font-size : 2em; /* attribute class A */}
.foo { color : green; /* attribute class B */}

Cuando se da un elemento del atributo class="foo", es útil pensar en ella no como heredar los atributos de la clase .foo, sino de clase de atributo A y clase B atributo . Es decir, el gráfico de herencia tiene un nivel de profundidad, con elementos derivados de clases de atributos y los selectores que especifican dónde van los bordes y determinan la precedencia cuando hay atributos competitivos (similar al orden de resolución del método).

ingrese la descripción de la imagen aquí

La implicación práctica para la programación es la siguiente. Digamos que tiene la hoja de estilo dada anteriormente y desea agregar una nueva clase .baz, donde debería tener la misma font-sizeque .foo. La solución ingenua sería esta:

.foo, .bar { font-weight : bold; font-size : 2em; /* attribute class A */}
.foo { color : green; /* attribute class B */}
.baz { font-size : 2em; /* attribute class C, hidden dependency! */}

ingrese la descripción de la imagen aquí

¡Cada vez que tengo que escribir algo dos veces me enojo tanto! No solo tengo que escribirlo dos veces, ahora no tengo forma de indicarlo programáticamente .fooy .bazdebería tener lo mismo font-size, ¡y he creado una dependencia oculta! Mi paradigma anterior sugeriría que debería abstraer el font-sizeatributo de la clase de atributo A :

.foo, .bar, .baz { font-size : 2em; /* attribute base class for A */}
.foo, .bar { font-weight : bold; /* attribute class A */}
.foo { color : green; /* attribute class B */}

ingrese la descripción de la imagen aquí

La queja principal aquí es que ahora tengo que volver a escribir cada selector de clase de atributo A de nuevo para especificar que los elementos que deben selecciona debe atributos también heredan de la clase base atributo A . Aún así, las alternativas son tener que recordar editar cada clase de atributo donde hay dependencias ocultas cada vez que algo cambia, o usar una herramienta de terceros. La primera opción hace reír a Dios, la segunda me da ganas de suicidarme.

Nathan Chappell
fuente
0

Si desea un preprocesador de texto más potente que LESS, consulte PPWizard:

http://dennisbareis.com/ppwizard.htm

Advertencia, el sitio web es realmente horrible y hay una pequeña curva de aprendizaje, pero es perfecto para construir código CSS y HTML a través de macros. Nunca he entendido por qué más codificadores web no lo usan.

BloDoe
fuente
11
El sitio web es realmente horrible.
nanofarad
¡Es irónico en un sitio web para un procesador html!
Ben Thurley
2
Sí, el sitio web es horrible, pero es más que eso. ¡Es difícil de leer y también me duele la cabeza!
ArtOfWarfare
1
Una buena cosa es que es compatible con Windows 3.1 a XP, jajaja
Alter Lagos
Una extraña herramienta no estándar, no me gusta.
berkus
-6

Puede lograr lo que desea si preprocesa sus archivos .css a través de php. ...

$something='color:red;'
$else='display:inline;';
echo '.something {'. $something .'}';
echo '.else {'. $something .'}';
echo '.somethingelse {'. $something  .$else '}';

...

Juan
fuente