Une classe CSS peut-elle hériter d'une ou plusieurs autres classes?


736

Je me sens stupide d'avoir été programmeur Web pendant si longtemps et de ne pas connaître la réponse à cette question, j'espère que c'est possible et je ne savais tout simplement pas ce que je pense être la réponse (c'est-à-dire que ce n'est pas possible) .

Ma question est de savoir s'il est possible de créer une classe CSS qui "hérite" d'une autre classe CSS (ou de plusieurs).

Par exemple, disons que nous avions:

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

Ce que j'aimerais faire, c'est quelque chose comme ceci:

.composite 
{
   .something;
   .else
}

où la classe ".composite" serait à la fois affichée en ligne et sur fond rouge


3
pensez plus à la cascade plutôt qu'à l'héritage, cela ne s'applique pas ici
blu

Réponses:


427

Il existe des outils comme LESS , qui vous permettent de composer du CSS à un niveau d'abstraction plus élevé similaire à ce que vous décrivez.

Moins appelle ces "Mixins"

Au lieu 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 pourrais dire

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

#header {
  .rounded_corners;
}

#footer {
  .rounded_corners;
}

37
wow, MOINS est à peu près exactement ce que je recherche ... c'est dommage qu'il ne soit pas pris en charge nativement, et qu'il soit écrit en Ruby (j'utilise ASP.NET MVC)
Joel Martinez

1
Oui, je suis aussi dans le monde ASP.NET, donc je ne l'ai pas déplacé dans mon flux de production.
Larsenal

Moins est beau et tentant ... mais je n'ai pas réussi à l'utiliser avec CSSEdit dans le même flux de travail - je ne l'ai donc pas encore totalement adopté.
Ryan Florence

1
Ouais MOINS est assez doux n'est-ce pas. J'ai travaillé sur un port .NET ici: nlesscss.codeplex.com .
Owen

77
au cas où vous atteindriez cela via google: le port .Net est maintenant
Eonasdan

310

Vous pouvez ajouter plusieurs classes à un seul élément DOM, par exemple

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

Les règles données dans des classes ultérieures (ou qui sont plus spécifiques) sont prioritaires. Donc, fourthclassdans ce type d'exemple, cela prévaut.

L'héritage ne fait pas partie de la norme CSS.


12
savez-vous si quelle classe prévaut, les dernières ou les 1ères et le comportement du navigateur est-il sûr? Disons que nous avons .firstClass {font-size:12px;} .secondClass {font-size:20px;}sera alors définitive font-sizeêtre 12pxou 20pxet est - ce sécuritaire croix navigateur?
Marco Demaio

27
La règle avec la spécificité la plus élevée sur le sélecteur l'emportera. Les règles de spécificité standard s'appliquent; dans votre exemple, puisque "premier" et "second" ont la même spécificité, la règle déclarée plus loin dans le CSS l'emportera.
Matt Bridges

19
J'aime l'idée d'utiliser du CSS pur (au lieu de MOINS) pour résoudre ce problème.
Alex

8
J'aime aussi l'idée de ne pas taper plusieurs classes plusieurs fois - ce qui est du travail O (n ^ 2) :)
Secret

3
Que faire si j'utilise une bibliothèque tierce et que je souhaite modifier la conception / HTML qu'elle fournit, mais que je ne peux pas modifier les fichiers CSS intégrés dans cette bibliothèque? Là, j'aurais besoin d'une sorte d'héritage dans les classes CSS.
Shivam

112

Oui, mais pas exactement avec cette syntaxe.

.composite,
.something { display:inline }

.composite,
.else      { background:red }

7
C'est nul, mais je suis content que nous ayons au moins ça!
Pacerier

3
Pourquoi ça craint? cela semble très bien. Je ne peux pas comprendre la différence entre le symbole virgule et la solution less.js.
Revious

21
Parce que si les classes .something et .else sont dans des fichiers différents et que vous ne pouvez pas les modifier, alors vous êtes coincé.
Alexandre Mélard

8
C'était la bonne réponse car elle répondait à la question en utilisant la syntaxe CSS pure. Cependant, la réponse la moins bonne est bonne.
raddevus

1
Ce devrait être la réponse exceptée.
eaglei22

66

Gardez ensemble vos attributs communs et attribuez à nouveau des attributs spécifiques (ou redéfinis).

/*  ------------------------------------------------------------------------------ */   
/*  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
C'est très proche d'une solution idéale, j'espère que les gens ne la rejetteront pas simplement parce qu'elle a obtenu peu de votes. En fait, l'un des problèmes les plus difficiles à propos de «l'héritage CSS» est que vous obtenez généralement un énorme logiciel Web déjà créé (par exemple, un commerce électronique ou un blog PHP célèbre logiciel) et qu'ils utilisent du code PHP qui a nativement gagné » t ajouter plusieurs classes aux éléments HTML qu'ils produisent. Cela vous oblige à vous déplacer et à jouer avec le code source (en perdant les modifications si vous effectuez une mise à niveau plus tard) pour le faire sortir ces classes supplémentaires. Avec cette approche, à la place, vous ne modifiez que le fichier CSS!
Dario Fumagalli

3
C'était exactement ce que je cherchais. Cela ne vaut-il rien que cette même approche fonctionne avec les sélecteurs CSS? Au lieu de spécifier, h1, h2, etcvous pouvez spécifier.selector1, .selector2, .etc
JeffryHouser

Je voulais dire que c'est précisément l'approche utilisée par w3 dans leur feuille de style html par défaut recommandée: [w3 CSS2]: w3.org/TR/CSS2/sample.html . J'essaie également de comprendre comment organiser le code CSS, et il semble que le paradigme soit inversé par rapport à l'héritage orienté objet typique: vous utilisez des classes (ou, plus généralement des sélecteurs) pour spécifier quels éléments héritent de quels attributs, mais vous héritez des attributs (du moins, c'est ainsi que la hiérarchie peut exister le plus facilement de manière logique), puis remplacez les attributs au niveau des sélecteurs plus spécifiques si nécessaire.
Nathan Chappell

51

Un élément peut prendre plusieurs classes:

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

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

Et c'est à peu près aussi proche que vous allez l'obtenir malheureusement. J'adorerais voir cette fonctionnalité, ainsi que les alias de classe un jour.


45

Non, tu ne peux pas faire quelque chose comme

.composite 
{
   .something;
   .else
}

Ce ne sont pas des noms de "classe" au sens OO. .somethinget ne .elsesont que des sélecteurs rien de plus.

Mais vous pouvez soit spécifier deux classes sur un élément

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

ou vous pourriez envisager une autre forme d'héritage

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

Où les paragraphes backgroundcolor et color sont hérités des paramètres de la div englobante qui est .foostylisée. Vous devrez peut-être vérifier la spécification exacte du W3C. inheritest par défaut pour la plupart des propriétés de toute façon mais pas pour tous.


1
yup, cette (première partie) était mon attente quand j'ai entendu parler de CSS pour la première fois au 20ème siècle ... et nous ne l'avons toujours pas, ils brûlent les performances sur certaines choses dynamiques alors que cela peut être statique composé juste avant l'application du CSS et il remplace le besoin de variables ("variables" statiques)
neu-rah

30

J'ai rencontré ce même problème et j'ai fini par utiliser une solution JQuery pour donner l'impression qu'une classe peut hériter d'autres classes.

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

Ceci trouvera tous les éléments avec la classe "composite" et ajoutera les classes "quelque chose" et "else" aux éléments. Donc, quelque chose comme ça <div class="composite">...</div>finira comme ça:
<div class="composite something else">...</div>


1
Le problème avec cette solution est que cela s'applique à tous les contrôles existants, si vous créez le contrôle après cet appel, il n'aura pas la nouvelle classe.
LuisEduardoSP

27

La manière SCSS pour l'exemple donné serait quelque chose comme:

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

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

Plus d'informations, consultez les bases de sass


Quelle est la valeur ajoutée par rapport à cela? .composite,.something { display:inline }et.composite,.else { background:red }
Pavel Gatnar

2
@PavelGatnar Vous pouvez réutiliser les définitions de .somethinget .elsedans d'autres définitions CSS.
Alter Lagos

16

Le mieux que vous puissiez faire est

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

N'oubliez pas:

div.something.else {

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

}

1
je ne le cherche pas, mais c'était constructif pour moi n__n
AgelessEssence

7

Dans le fichier Css:

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

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

2
Alors, quel sera le résultat font-size?
abatishchev

La taille de la police serait de 12 pixels pour "p.Title" car elle est définie après la première du fichier. il remplace la première taille de police.
YWE

@YWE: Cela signifie-t-il que les déclarations devraient en fait être l'inverse par rapport à ce qui est écrit dans cette réponse (du moins si nous voulons par exemple être illustratif)? Si le dernier défini prévaut, le font-size: 16pxne peut jamais prendre effet, non?
OR Mapper

@ORMapper - ce qui se produit généralement, c'est que la première déclaration se trouve dans un fichier css commun, partagé par plusieurs pages. Ensuite, la deuxième déclaration se trouve dans un deuxième fichier CSS, utilisé uniquement sur certaines pages. Et importé après le fichier css commun. Ces pages utilisent donc la valeur "dernière vue" de 12px.
ToolmakerSteve

7

Je me rends compte que cette question est maintenant très ancienne mais, ici ça ne va rien!

Si l'intention est d'ajouter une seule classe qui implique les propriétés de plusieurs classes, en tant que solution native, je recommanderais d'utiliser JavaScript / jQuery (jQuery n'est vraiment pas nécessaire mais certainement utile)

Si vous avez, par exemple, .umbrellaClassqui "hérite" de .baseClass1et .baseClass2vous pourriez avoir du JavaScript qui se déclenche.

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

Maintenant, tous les éléments de .umbrellaClassauront toutes les propriétés des deux .baseClasss. Notez que, comme l'héritage OOP, .umbrellaClasspeut ou peut ne pas avoir ses propres propriétés.

La seule mise en garde ici consiste à déterminer s'il existe des éléments créés dynamiquement qui n'existeront pas lorsque ce code se déclenchera, mais il existe également des moyens simples de contourner cela.

Sucks css n'a pas d'héritage natif, cependant.


1
Cette approche a déjà été suggérée dans la réponse de @ DHoover de 2013.
Bryan

6

Un timing parfait : je suis passé de cette question à mon email, pour trouver un article sur Less , une librairie Ruby qui fait entre autres:

Puisque super ressemble à footer, mais avec une police différente, j'utiliserai la technique d'inclusion de classe de Less (ils l'appellent un mixin) pour lui dire d'inclure également ces déclarations:

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

Juste au moment où je pensais que LESS ne pouvait plus me surprendre ... Je ne savais pas que vous pouviez importer le formatage d'un autre bloc comme celui-ci. Bon conseil.
Daniel Rippstein

4

Malheureusement, CSS ne fournit pas d'héritage comme le font les langages de programmation comme C ++, C # ou Java. Vous ne pouvez pas déclarer une classe CSS puis l'étendre avec une autre classe CSS.

Cependant, vous pouvez appliquer plusieurs classes à une balise de votre balisage ... auquel cas il existe un ensemble sophistiqué de règles qui déterminent les styles réels qui seront appliqués par le navigateur.

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

CSS recherchera tous les styles qui peuvent être appliqués en fonction de votre balisage et combinera les styles CSS de ces multiples règles ensemble.

En règle générale, les styles sont fusionnés, mais lorsque des conflits surviennent, le style déclaré plus tard l'emporte généralement (sauf si l'attribut! Important est spécifié sur l'un des styles, auquel cas il gagne). De plus, les styles appliqués directement à un élément HTML ont priorité sur les styles de classe CSS.


Votre réponse est venue comme premier résultat sur Google pour moi et a été utile. Cela dit, j'ai une astuce pour vous - si vous proposez une solution, il est préférable d'éviter de commencer des phrases négativement (malheureusement, CSS ne fournit pas d'héritage ..) Je sais que toute personne possédant la patience appropriée lira la suite pour découvrir votre solution intéressante mais parfois les gens manquent de patience et peuvent se précipiter pour conclure que ce qu'ils essaient de faire est impossible. Pour avoir les meilleures chances d'aider les autres, vous pouvez commencer par quelque chose comme "Bien que CSS n'ait pas d'héritage, vous pouvez réaliser ce dont vous avez besoin ..."
egmfrs

4

Il y a aussi SASS, que vous pouvez trouver sur http://sass-lang.com/ . Il y a une balise @extend, ainsi qu'un système de type mix-in. (Rubis)

C'est une sorte de concurrent de LESS.


4

Ce n'est pas possible en CSS.

La seule chose prise en charge en CSS est plus spécifique qu'une autre règle:

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

Un span avec la classe "myclass" aura les deux propriétés.

Une autre façon consiste à spécifier deux classes:

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

Le style de "else" remplacera (ou ajoutera) le style de "quelque chose"


Pour tous les styles dans un fichier, il existe une solution de type héritage en CSS, voir mon article.
Pavel Gatnar

3

Vous pouvez appliquer plusieurs classes CSS à un élément par quelque chose comme ceci class = "else else"


3

Comme d'autres l'ont dit, vous pouvez ajouter plusieurs classes à un élément.

Mais ce n'est pas vraiment le point. J'ai votre question sur l'héritage. Le vrai point est que l'héritage en CSS ne se fait pas via des classes, mais via des hiérarchies d'éléments. Donc, pour modéliser les traits hérités, vous devez les appliquer à différents niveaux d'éléments dans le DOM.


Il est préférable de créer des définitions CSS de type héritage au lieu d'utiliser toute la chaîne de classe de composition, voir mon article.
Pavel Gatnar

2

Je cherchais ça comme un fou aussi et je l'ai compris en essayant différentes choses: P ... Eh bien, vous pouvez le faire comme ça:

composite.something, composite.else
{
    blblalba
}

Cela a soudainement fonctionné pour moi :)


2

Dans des circonstances spécifiques, vous pouvez faire un héritage "soft":

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

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

Cela ne fonctionne que si vous ajoutez la classe .composite à un élément enfant. Il s'agit d'un héritage "doux" car toutes les valeurs non spécifiées dans .composite ne sont évidemment pas héritées. Gardez à l'esprit qu'il serait toujours moins de caractères d'écrire simplement "en ligne" et "rouge" au lieu de "hériter".

Voici une liste de propriétés et si elles le font automatiquement ou non: https://www.w3.org/TR/CSS21/propidx.html


2

Bien que l'héritage direct ne soit pas possible.

Il est possible d'utiliser une classe (ou id) pour une balise parent, puis d'utiliser des combinateurs CSS pour modifier le comportement des balises enfants à partir de sa hiérarchie.

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>

Je ne suggérerais pas d'utiliser autant de portées comme l'exemple, mais ce n'est qu'une preuve de concept. De nombreux bogues peuvent encore survenir lors de la tentative d'application de CSS de cette manière. (Par exemple, modification des types de décoration de texte).


2

Less et Sass sont des pré-processeurs CSS qui étendent le langage CSS de manière précieuse. L'une des nombreuses améliorations qu'ils offrent n'est que l'option que vous recherchez. Il y a de très bonnes réponses avec Less et j'ajouterai la solution Sass.

Sass a une option d'extension qui permet à une classe d'être entièrement étendue à une autre. En savoir plus sur l'extension, vous pouvez lire dans cet article



1

CSS ne fait pas vraiment ce que vous demandez. Si vous voulez écrire des règles avec cette idée composite à l'esprit, vous voudrez peut-être consulter la boussole . C'est un cadre de feuille de style qui ressemble au Less déjà mentionné.

Il vous permet de faire des mixins et toutes ces bonnes affaires.


En ajoutant plus de détails ci-dessus, Compass aka Sass le fait via Extend, PlaceHolders Mixins vs Extend , des informations plus détaillées sur PlaceHolders
Abhijeet

1

Pour ceux qui ne sont pas satisfaits des (excellents) articles mentionnés, vous pouvez utiliser vos compétences en programmation pour créer une variable (PHP ou autre) et lui faire stocker les noms de plusieurs classes.

C'est le meilleur hack que j'ai pu trouver.

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

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

Ensuite, appliquez la variable globale à l'élément que vous désirez plutôt qu'aux noms de classe eux-mêmes

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


1

Ne pensez pas aux classes CSS comme des classes orientées objet, pensez-y simplement comme un outil parmi d'autres sélecteurs pour spécifier les classes d'attributs par lesquelles un élément html est stylisé. Considérez tout entre les accolades comme la classe d'attributs , et les sélecteurs sur le côté gauche indiquent aux éléments qu'ils sélectionnent pour hériter des attributs de la classe d'attributs . Exemple:

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

Lorsqu'un élément est donné l'attribut class="foo", il est utile de penser non pas comme héritant des attributs de la classe .foo, mais de classe attribut A et classe d'attributs B . C'est-à-dire que le graphe d'héritage a un niveau de profondeur, avec des éléments dérivés des classes d'attributs , et les sélecteurs spécifiant où vont les arêtes, et déterminant la priorité quand il y a des attributs concurrents (similaire à l'ordre de résolution des méthodes).

entrez la description de l'image ici

L'implication pratique pour la programmation est la suivante. Supposons que vous ayez la feuille de style indiquée ci-dessus et que vous souhaitiez ajouter une nouvelle classe .baz, où elle devrait avoir la même chose font-sizeque .foo. La solution naïve serait la suivante:

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

entrez la description de l'image ici

Chaque fois que je dois taper quelque chose deux fois, je suis tellement en colère! Non seulement je dois écrire deux fois, maintenant je n'ai aucun moyen d'indiquer que programatically .fooet .bazdoit avoir la même font-size, et je l' ai créé une dépendance cachée! Mon paradigme ci-dessus suggère que je devrais extraire l' font-sizeattribut de la classe d'attributs 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 */}

entrez la description de l'image ici

La plainte principale ici est que maintenant je dois retaper chaque sélecteur de classe attribut A nouveau de préciser que les éléments qu'ils doivent sélectionner les attributs devraient hériter de la classe de base de l' attribut A . Pourtant, les alternatives sont de ne pas oublier de modifier chaque classe d'attributs où il y a des dépendances cachées à chaque fois que quelque chose change, ou d'utiliser un outil tiers. La première option fait rire Dieu, la seconde me donne envie de me tuer.


0

Si vous voulez un préprocesseur de texte plus puissant que LESS, consultez PPWizard:

http://dennisbareis.com/ppwizard.htm

Attention, le site Web est vraiment hideux et il y a une petite courbe d'apprentissage, mais il est parfait pour créer du code CSS et HTML via des macros. Je n'ai jamais compris pourquoi plus de codeurs Web ne l'utilisent pas.


11
Le site Web est vraiment hideux.
nanofarad

Un peu ironique sur un site web pour un processeur html!
Ben Thurley

2
Oui, le site Web est hideux, mais c'est plus que cela. C'est difficile à lire et ça me fait mal à la tête aussi!
ArtOfWarfare

1
Une bonne chose qu'il est compatible avec Windows 3.1 à XP, lol
Alter Lagos

Un outil non standard bizarre, pas comme.
berkus

-6

Vous pouvez obtenir ce que vous voulez si vous prétraitez vos fichiers .css via php. ...

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

...

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.