Una classe CSS può ereditare una o più altre classi?


736

Mi sento stupido per essere stato un programmatore web per così tanto tempo e non conoscendo la risposta a questa domanda, spero davvero che sia possibile e non sapevo piuttosto che ciò che penso sia la risposta (che è che non è possibile) .

La mia domanda è se è possibile creare una classe CSS che "eredita" da un'altra classe CSS (o più di una).

Ad esempio, supponiamo che avessimo:

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

Quello che mi piacerebbe fare è qualcosa del genere:

.composite 
{
   .something;
   .else
}

dove la classe ".composite" verrebbe visualizzata sia in linea che con uno sfondo rosso


3
pensa più a cascata che a eredità, non si applica qui
blu

Risposte:


427

Esistono strumenti come LESS , che ti consentono di comporre CSS a un livello superiore di astrazione simile a quello che descrivi.

Meno chiama questi "Mixin"

Invece di

/* 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;
}

Potresti dire

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

#header {
  .rounded_corners;
}

#footer {
  .rounded_corners;
}

37
wow, MENO è praticamente esattamente quello che sto cercando ... è un peccato che non sia supportato in modo nativo e che sia scritto in Ruby (sto usando ASP.NET MVC)
Joel Martinez,

1
Sì, anche io sono nel mondo ASP.NET, quindi non l'ho spostato nel mio flusso di lavoro di produzione.
Larsenal,

Meno è bello e allettante ... ma non ho avuto molto successo nell'usarlo con CSSEdit nello stesso flusso di lavoro - quindi non l'ho ancora adottato del tutto.
Ryan Florence,

1
Sì, MENO è piuttosto dolce, vero? In realtà ho lavorato su una porta .NET qui: nlesscss.codeplex.com .
Owen,

77
nel caso in cui lo raggiungiate tramite google: la porta .Net è ora qui
Eonasdan,

310

È possibile aggiungere più classi a un singolo elemento DOM, ad es

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

Le regole fornite nelle classi successive (o che sono più specifiche) hanno la precedenza. Quindi fourthclassprevale in quel tipo di esempio.

L'ereditarietà non fa parte dello standard CSS.


12
sai se prevale quale classe, l'ultima o la prima ed è sicuro il comportamento tra browser? Diciamo che abbiamo .firstClass {font-size:12px;} .secondClass {font-size:20px;}verrà poi finale font-sizesia 12pxo 20pxe Questa funzione è sicura cross browser?
Marco Demaio,

27
Vincerà la regola con la massima specificità sul selettore. Si applicano le regole di specificità standard; nel tuo esempio, poiché "primo" e "secondo" hanno la stessa specificità, vincerà la regola dichiarata successivamente nel CSS.
Matt Bridges,

19
Mi piace l'idea di usare CSS puro (invece di MENO) per risolvere questo problema.
Alex

8
Mi piace anche l'idea di non scrivere più classi più volte - Che è O (n ^ 2) lavoro :)
Segreto

3
Cosa succede se sto usando una libreria di terze parti e voglio modificare il design / HTML che fornisce, ma non posso cambiare i file CSS incorporati in quella libreria? Lì avrei bisogno di una sorta di eredità nelle classi CSS.
Shivam,

112

Sì, ma non esattamente con quella sintassi.

.composite,
.something { display:inline }

.composite,
.else      { background:red }

7
Questo schifo, ma sono contento che almeno abbiamo questo!
Pacerier,

3
Perché fa schifo? sembra molto buono. Non riesco a capire la differenza tra il simbolo della virgola e la soluzione less.js.
Revious

21
Perché se le classi .something e .else sono in file diversi e non è possibile modificarli, allora sei bloccato.
Alexandre Mélard,

8
Questa è stata la risposta giusta perché ha risposto alla domanda utilizzando la sintassi CSS pura. La risposta meno è buona da sapere però.
Raddevus,

1
Questa dovrebbe essere la risposta esclusa.
eaglei22,

66

Mantieni insieme i tuoi attributi comuni e assegna nuovamente attributi specifici (o di sostituzione).

/*  ------------------------------------------------------------------------------ */   
/*  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;
}

2
Questo è molto vicino a una soluzione ideale, spero che la gente non lo scarti solo perché ha ottenuto pochi voti. In effetti, uno dei problemi più impegnativi sulla "eredità CSS" è che di solito si ottiene un enorme software Web già realizzato (ad esempio un software di PHP per e-commerce o blog) e che utilizzano un codice PHP che ha vinto nativamente " t aggiungere più classi agli elementi HTML che escono. Questo ti costringe a andare in giro e pasticciare con il codice sorgente (perdendo le modifiche se esegui l'aggiornamento in seguito) per renderlo in uscita quelle classi aggiuntive. Con questo approccio, invece, modifichi sempre e solo il file CSS!
Dario Fumagalli,

3
Questo era esattamente quello che stavo cercando. Non vale nulla questo stesso approccio funzionerà con i selettori CSS? Invece di specificare h1, h2, etcè possibile specificare.selector1, .selector2, .etc
JeffryHouser

Volevo commentare che questo è esattamente l'approccio usato da w3 nel loro foglio di stile html predefinito raccomandato: [w3 CSS2]: w3.org/TR/CSS2/sample.html . Sto anche cercando di capire come organizzare il codice CSS e sembra che il paradigma sia invertito rispetto alla tipica eredità orientata agli oggetti: usi le classi (o, più in generale i selettori) per specificare quali elementi ereditano quali attributi, ma erediti gli attributi (almeno, questo è il modo in cui la gerarchia può esistere più facilmente logicamente), quindi sovrascrivi gli attributi sui selettori più specifici quando necessario.
Nathan Chappell il

51

Un elemento può assumere più classi:

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

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

E questo è sfortunatamente vicino. Mi piacerebbe vedere questa funzione, insieme agli alias di classe un giorno.


45

No, non puoi fare qualcosa del genere

.composite 
{
   .something;
   .else
}

Non si tratta di nomi di "classe" in senso OO. .somethinge non .elsesono altro che selettori.

Ma puoi specificare due classi su un elemento

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

o potresti esaminare un'altra forma di eredità

.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>

Dove i paragrafi backgroundcolor e color sono ereditati dalle impostazioni nel div allegato che è in .foostile. Potrebbe essere necessario controllare l'esatta specifica W3C. inheritè comunque predefinito per la maggior parte delle proprietà, ma non per tutti.


1
sì, questa (prima parte) era la mia aspettativa quando ho sentito parlare per la prima volta del CSS nel 20 ° secolo ... e ancora non ce l'abbiamo, stanno bruciando le prestazioni su alcune cose dinamiche mentre questo può essere composto staticamente appena prima dell'applicazione css e sostituisce la necessità di variabili ("variabili" statiche)
neu-rah,

30

Ho riscontrato questo stesso problema e ho finito per usare una soluzione JQuery per far sembrare che una classe possa ereditare altre classi.

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

Questo troverà tutti gli elementi con la classe "composito" e aggiungerà le classi "qualcosa" e "altro" agli elementi. Quindi qualcosa del genere <div class="composite">...</div>finirà così:
<div class="composite something else">...</div>


1
Il problema con questa soluzione è che si applica a tutti i controlli esistenti, se si crea il controllo dopo questa chiamata, non avrà la nuova classe.
LuisEduardoSP,

27

Il modo SCSS per l'esempio dato sarebbe qualcosa del tipo:

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

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

Maggiori informazioni, controlla le basi di sass


Qual è il valore aggiunto rispetto a questo? .composite,.something { display:inline }e.composite,.else { background:red }
Pavel Gatnar l'

2
@PavelGatnar È possibile riutilizzare le definizioni di .somethinge .elsein altre definizioni CSS.
Alter Lagos,

16

Il meglio che puoi fare è questo

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>

12

Non dimenticare:

div.something.else {

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

}

1
non lo cerco, ma questo è stato costruttivo per me n__n
AgelessEssence

7

Nel file Css:

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

p.SubTitle p.Title
{
   font-size: 12px;
}

2
Quindi quale sarà il risultato font-size?
abatishchev,

La dimensione del carattere sarebbe 12px per "p.Title" perché è definita dopo la prima nel file. sovrascrive la prima dimensione del carattere.
YWE,

@YWE: Significa che le dichiarazioni dovrebbero in realtà essere al contrario rispetto a quanto è scritto in questa risposta (almeno se vogliamo che l'esempio sia illustrativo)? Se prevale l'ultimo definito, font-size: 16pxnon potrà mai avere effetto, giusto?
OR Mapper,

@ORMapper: in genere ciò che accade è che la prima dichiarazione è in un file css comune, condiviso da più pagine. Quindi la seconda dichiarazione è in un secondo file CSS, usato solo su determinate pagine. E importato dopo il file css comune. Quindi quelle pagine usano il valore "ultimo accesso" di 12px.
ToolmakerSteve

7

Mi rendo conto che questa domanda è ormai molto antica ma, qui non c'è niente!

Se l'intento è quello di aggiungere una singola classe che implica le proprietà di più classi, come soluzione nativa, consiglierei di usare JavaScript / jQuery (jQuery non è davvero necessario ma sicuramente utile)

Se hai, ad esempio, .umbrellaClass"eredita" da .baseClass1e .baseClass2potresti avere un JavaScript pronto per essere attivato.

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

Ora tutti gli elementi di .umbrellaClassavranno tutte le proprietà di entrambi .baseClass. Si noti che, come l'eredità OOP,.umbrellaClass può avere o meno le proprie proprietà.

L'unico avvertimento qui è considerare se ci sono elementi creati dinamicamente che non esistono quando questo codice viene attivato, ma ci sono anche semplici modi per aggirare questo.

Sucks css non ha eredità nativa, però.


1
Questo approccio è già stato suggerito nella risposta di @ DHoover del 2013.
Bryan,

6

Tempismo perfetto : sono passato da questa domanda alla mia e-mail per trovare un articolo su Less , una libreria di Ruby che tra l'altro fa questo:

Dato che super sembra proprio footer, ma con un carattere diverso, userò la tecnica di inclusione della classe di Less (lo chiamano un mixin) per dirgli di includere anche queste dichiarazioni:

#super {
  #footer;
  font-family: cursive;
}

Proprio quando pensavo che MENO non potesse più sorprendermi ... Non avevo idea che potessi importare la formattazione da un altro blocco come questo. Ottimo consiglio
Daniel Rippstein,

4

Sfortunatamente, i CSS non forniscono "ereditarietà" come fanno i linguaggi di programmazione come C ++, C # o Java. Non è possibile dichiarare una classe CSS e quindi estenderla con un'altra classe CSS.

Tuttavia, puoi applicare più di una singola classe a un tag nel tuo markup ... nel qual caso esiste un insieme sofisticato di regole che determinano quali stili effettivi verranno applicati dal browser.

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

I CSS ricercheranno tutti gli stili che possono essere applicati in base al markup e combineranno insieme gli stili CSS da quelle regole multiple.

In genere, gli stili vengono uniti, ma quando sorgono conflitti, lo stile dichiarato successivamente vincerà generalmente (a meno che l'attributo! Important sia specificato su uno degli stili, nel qual caso vince). Inoltre, gli stili applicati direttamente a un elemento HTML hanno la precedenza sugli stili di classe CSS.


La tua risposta è arrivata come primo risultato su Google per me ed è stata utile. Detto questo, ho un suggerimento per te: se stai offrendo una soluzione, è meglio evitare di iniziare le frasi negativamente (Sfortunatamente, i CSS non forniscono ereditarietà ..) So che chiunque con adeguata pazienza continuerebbe a leggere per scoprire la tua bella soluzione ma a volte le persone stanno esaurendo la pazienza e possono arrivare alla conclusione che ciò che stanno cercando di fare è impossibile. Per avere le migliori possibilità di aiutare gli altri, potresti iniziare con qualcosa del tipo "Anche se i CSS non hanno eredità, puoi ottenere ciò di cui hai bisogno ..."
egmfrs,

4

C'è anche SASS, che puoi trovare su http://sass-lang.com/ . C'è un tag @extend, oltre a un sistema di tipo mix-in. (Rubino)

È un po 'un concorrente di MENO.


4

Questo non è possibile nei CSS.

L'unica cosa supportata nei CSS è essere più specifici di un'altra regola:

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

Un intervallo con classe "myclass" avrà entrambe le proprietà.

Un altro modo è quello di specificare due classi:

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

Lo stile di "else" sostituirà (o aggiungerà) lo stile di "qualcosa"


Per tutti gli stili in 1 file c'è una soluzione simile all'ereditarietà nei CSS, vedi il mio post.
Pavel Gatnar,

3

Puoi applicare più di una classe CSS a un elemento usando qualcosa come questa class = "qualcos'altro"


3

Come altri hanno già detto, puoi aggiungere più classi a un elemento.

Ma non è questo il punto. Ricevo la tua domanda sull'eredità. Il vero punto è che l'ereditarietà nei CSS non avviene attraverso le classi, ma attraverso le gerarchie di elementi. Quindi, per modellare i tratti ereditati è necessario applicarli a diversi livelli di elementi nel DOM.


È meglio creare definizioni CSS simili all'ereditarietà invece di usare tutta la catena di classi di composizione, vedi il mio post.
Pavel Gatnar,

2

Lo stavo anche cercando come un matto e l'ho appena capito provando diverse cose: P ... Beh, puoi farlo in quel modo:

composite.something, composite.else
{
    blblalba
}

Improvvisamente ha funzionato per me :)


2

In circostanze specifiche è possibile eseguire un'eredità "soft":

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

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

Funziona solo se stai aggiungendo la classe .composite a un elemento figlio. È eredità "soft" perché tutti i valori non specificati in .composite non vengono ereditati ovviamente. Tieni presente che sarebbe comunque meno caratteri scrivere semplicemente "inline" e "red" invece di "ereditare".

Ecco un elenco di proprietà e se lo fanno automaticamente: https://www.w3.org/TR/CSS21/propidx.html


2

Mentre l'ereditarietà diretta non è possibile.

È possibile utilizzare una classe (o id) per un tag padre e quindi utilizzare i combinatori CSS per modificare il comportamento del tag figlio dalla sua gerarchia.

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>

Non consiglierei di usare così tante campate come nell'esempio, tuttavia è solo una prova di concetto. Ci sono ancora molti bug che possono sorgere quando si cerca di applicare i CSS in questo modo. (Ad esempio, modifica dei tipi di decorazione del testo).


2

Less e Sass sono pre-processori CSS che estendono il linguaggio CSS in modi preziosi. Solo uno dei molti miglioramenti che offrono è solo l'opzione che stai cercando. Ci sono alcune risposte molto buone con Less e aggiungerò la soluzione Sass.

Sass ha un'opzione di estensione che consente di estendere completamente una classe a un'altra. Maggiori informazioni sull'estensione che puoi leggere in questo articolo



1

CSS in realtà non fare quello che stai chiedendo. Se vuoi scrivere regole pensando a quell'idea composita, potresti voler dare un'occhiata alla bussola . È un framework per fogli di stile che sembra simile al già menzionato Less.

Ti permette di fare mixin e tutto quel buon affare.


Aggiungendo ulteriori dettagli sopra, Compass aka Sass lo fa tramite Extend, PlaceHolders Mixins vs Extend , informazioni più dettagliate su PlaceHolders
Abhijeet

1

Per coloro che non sono soddisfatti dei post (eccellenti) menzionati, puoi usare le tue abilità di programmazione per creare una variabile (PHP o qualunque) e fare in modo che memorizzi i nomi di più classi.

Questo è il miglior trucco che ho potuto inventare.

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

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

Quindi applica la variabile globale all'elemento desiderato anziché i nomi delle classi stessi

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


1

Non pensare alle classi CSS come classi orientate agli oggetti, considerale semplicemente uno strumento tra gli altri selettori per specificare da quali classi di attributo è disegnato un elemento html. Pensa a tutto tra le parentesi graffe come alla classe di attributo e i selettori sul lato sinistro dicono agli elementi che selezionano per ereditare gli attributi dalla classe di attributo . Esempio:

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

Quando un elemento è dato l'attributo class="foo", è utile pensare ad esso non come ereditare attributi dalla classe .foo, ma dalla classe attributo A e di classe B attributo . Vale a dire, il grafico dell'ereditarietà è profondo un livello, con elementi derivanti da classi di attributi e i selettori che specificano dove vanno i bordi e determinano la precedenza quando ci sono attributi in competizione (simile all'ordine di risoluzione del metodo).

inserisci qui la descrizione dell'immagine

L'implicazione pratica per la programmazione è questa. Diciamo che avete il foglio di stile di cui sopra, e si desidera aggiungere una nuova classe .baz, dove dovrebbe avere lo stesso font-sizecome .foo. La soluzione ingenua sarebbe questa:

.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! */}

inserisci qui la descrizione dell'immagine

Ogni volta che devo digitare qualcosa due volte mi arrabbio così tanto! Non solo devo scriverlo due volte, ora non ho modo di indicarlo programmaticamente .fooe .bazdovrei avere lo stesso font-size, e ho creato una dipendenza nascosta! Il mio paradigma sopra suggerirebbe che dovrei sottrarre l' font-sizeattributo dalla classe di attributi 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 */}

inserisci qui la descrizione dell'immagine

La lamentela principale qui è che ora devo digitare nuovamente ogni selettore dalla classe di attributi A per specificare che gli elementi che dovrebbero selezionare dovrebbero anche ereditare gli attributi dalla classe di base A degli attributi . Tuttavia, le alternative devono ricordare di modificare ogni classe di attributo in cui vi sono dipendenze nascoste ogni volta che qualcosa cambia o di utilizzare uno strumento di terze parti. La prima opzione fa ridere Dio, la seconda mi fa venir voglia di uccidermi.


0

Se desideri un preprocessore di testo più potente di MENO, dai un'occhiata a PPWizard:

http://dennisbareis.com/ppwizard.htm

Avvertire il sito Web è davvero orribile e c'è una piccola curva di apprendimento, ma è perfetto per creare codice CSS e HTML tramite macro. Non ho mai capito perché più codificatori web non lo usano.


11
Il sito web è davvero orribile.
nanofarad,

Un po 'ironico su un sito Web per un processore HTML!
Ben Thurley,

2
Sì, il sito web è orribile, ma è molto più di questo. È difficile da leggere e mi fa male anche la testa!
ArtOfWarfare,

1
Una buona cosa che è compatibile con Windows 3.1 a XP, lol
Alter Lagos

Uno strumento bizzarro non standard, non mi piace.
Berkus,

-6

Puoi ottenere ciò che desideri se preprocedi i tuoi file .css tramite php. ...

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

...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.