Czy klasa CSS może dziedziczyć jedną lub więcej innych klas?


735

Czuję się głupio, że od tak dawna jestem programistą i nie znam odpowiedzi na to pytanie, mam nadzieję, że jest to możliwe i po prostu nie wiedziałem raczej o tym, niż jak sądzę (jest to niemożliwe) .

Moje pytanie brzmi, czy można stworzyć klasę CSS, która „odziedziczy” po innej klasie CSS (lub więcej niż jednej).

Powiedzmy, że mieliśmy:

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

Chciałbym zrobić coś takiego:

.composite 
{
   .something;
   .else
}

gdzie klasa „.composite” wyświetlałaby się w linii i miała czerwone tło


3
pomyśl więcej o kaskadowaniu niż o dziedziczeniu, nie dotyczy to tutaj
blu

Odpowiedzi:


427

Istnieją narzędzia takie jak LESS , które pozwalają komponować CSS na wyższym poziomie abstrakcji podobnym do tego, co opisujesz.

Mniej nazywa te „Mixiny”

Zamiast

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

Można powiedzieć

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

#header {
  .rounded_corners;
}

#footer {
  .rounded_corners;
}

37
wow, LESS jest dokładnie tym, czego szukam ... szkoda, że ​​nie jest obsługiwany natywnie i że jest napisany w Ruby (używam ASP.NET MVC)
Joel Martinez

1
Tak, jestem też w świecie ASP.NET, więc nie przeniosłem go do mojego procesu produkcyjnego.
Larsenal

Mniej jest piękne i kuszące ... ale nie odniosłem sukcesu, używając go z CSSEdit w tym samym przepływie pracy - więc jeszcze go całkowicie nie adoptowałem.
Ryan Florence,

1
Tak, MNIEJ jest całkiem słodki, prawda? Właśnie pracowałem na porcie .NET tutaj: nlesscss.codeplex.com .
Owen

77
w przypadku, gdy osiągnie to poprzez google: port Net jest teraz tutaj
Eonasdan

309

Możesz dodać wiele klas do jednego elementu DOM, np

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

Reguły podane w późniejszych klasach (lub które są bardziej szczegółowe) zastępują. Więc…fourthclass w tym przykładzie zwycięża.

Dziedziczenie nie jest częścią standardu CSS.


12
czy wiesz, która klasa zwycięży, ostatnia czy pierwsza i czy zachowanie w różnych przeglądarkach jest bezpieczne? Powiedzmy, że mamy .firstClass {font-size:12px;} .secondClass {font-size:20px;}wtedy ostateczna font-sizebyć 12pxalbo 20pxi ten krzyż jest bezpieczna przeglądarka?
Marco Demaio

27
Reguła o najwyższej specyficzności na selektorze wygrywa. Obowiązują standardowe zasady specyficzności; w twoim przykładzie, ponieważ „pierwszy” i „drugi” mają tę samą specyfikę, reguła zadeklarowana później w CSS wygra.
Matt Bridges

19
Podoba mi się pomysł użycia czystego CSS (zamiast MNIEJ) do rozwiązania tego problemu.
Alex

8
Podoba mi się również pomysł, aby nie wpisywać wielu klas wiele razy - co jest pracą O (n ^ 2) :)
Secret

3
Co się stanie, jeśli używam biblioteki innej firmy i chcę zmodyfikować projekt / kod HTML, ale nie mogę zmienić wbudowanych plików css w tej bibliotece? Potrzebowałbym pewnego rodzaju dziedziczenia w klasach css.
Shivam

112

Tak, ale nie dokładnie z tą składnią.

.composite,
.something { display:inline }

.composite,
.else      { background:red }

7
To do bani, ale cieszę się, że przynajmniej to mamy!
Pacerier,

3
Dlaczego to jest do bani? wydaje się bardzo dobrze. Nie rozumiem różnicy między symbolem przecinka a rozwiązaniem less.js.
Revious

21
Ponieważ jeśli klasy .something i .else znajdują się w różnych plikach i nie można ich modyfikować, oznacza to, że utkniesz.
Alexandre Mélard,

8
To była prawidłowa odpowiedź, ponieważ odpowiedziała na pytanie przy użyciu czystej składni CSS. Warto jednak wiedzieć mniej odpowiedzi.
raddevus,

1
To powinna być wyjątek.
eaglei22

66

Trzymaj wspólne atrybuty razem i ponownie przypisuj określone (lub zastępuj) atrybuty.

/*  ------------------------------------------------------------------------------ */   
/*  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
Jest to bardzo zbliżone do idealnego rozwiązania, mam nadzieję, że ludzie nie odrzucą go tylko dlatego, że uzyskał kilka głosów. W rzeczywistości jednym z najtrudniejszych problemów związanych z „dziedziczeniem CSS” jest to, że zwykle otrzymujesz już stworzone, ogromne oprogramowanie internetowe (na przykład e-commerce lub słynne oprogramowanie blogowe PHP) i używają kodu PHP, który natywnie wygrał ” t dodać wiele klas do tworzonych przez siebie elementów HTML. Zmusza to do obejścia kodu źródłowego (utraty zmian w przypadku późniejszej aktualizacji), aby wygenerować te dodatkowe klasy. Dzięki temu podejściu edytujesz tylko plik CSS!
Dario Fumagalli,

3
Właśnie tego szukałem. Czy nic nie jest warte, aby to samo podejście działało z Selektorami CSS? Zamiast sprecyzowania h1, h2, etcmożna podać.selector1, .selector2, .etc
JeffryHouser

Chciałem skomentować, że właśnie takie podejście zastosowano w3 w zalecanym domyślnym arkuszu stylów HTML: [w3 CSS2]: w3.org/TR/CSS2/sample.html . Próbuję również opanować sposób organizowania kodu css i wydaje się, że paradygmat jest odwrócony w porównaniu do typowego dziedziczenia obiektowego: używasz klas (lub, bardziej ogólnie, selektorów), aby określić, które elementy dziedziczą, które atrybuty, ale dziedziczysz atrybuty (przynajmniej w ten sposób hierarchia może najłatwiej istnieć logicznie), a następnie, w razie potrzeby, zastępuj atrybuty w bardziej szczegółowych selektorach.
Nathan Chappell,

50

Element może przyjmować wiele klas:

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

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

I to jest tak blisko, jak niestety się zbliżysz. Chciałbym kiedyś zobaczyć tę funkcję wraz z aliasami klas.


44

Nie, nie możesz zrobić czegoś takiego

.composite 
{
   .something;
   .else
}

To nie są nazwy „klasowe” w sensie OO. .somethingi .elsesą tylko selektorami.

Ale możesz albo określić dwie klasy dla elementu

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

lub możesz spojrzeć na inną formę dziedziczenia

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

Gdzie akapity kolor tła i kolor są dziedziczone z ustawień w otaczającym div, który jest w .foostylu. Może być konieczne sprawdzenie dokładnej specyfikacji W3C. inheriti tak jest domyślny dla większości właściwości, ale nie dla wszystkich.


1
tak, ta (pierwsza część) była moim oczekiwaniem, kiedy po raz pierwszy usłyszałem o CSS w XX wieku ... i wciąż go nie mamy, nagrywają wydajność na niektórych dynamicznych rzeczach, podczas gdy może to być statyczna kompozycja tuż przed zastosowaniem css i zastępuje potrzebę zmiennych (statycznych „zmiennych”)
neu-rah

30

Natknąłem się na ten sam problem i ostatecznie skorzystałem z rozwiązania JQuery, aby wyglądało na to, że klasa może dziedziczyć inne klasy.

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

Znajduje to wszystkie elementy z klasą „composite” i dodaje klasy „coś” i „else” do elementów. Coś w stylu<div class="composite">...</div> skończy się tak:
<div class="composite something else">...</div>


1
Problem z tym rozwiązaniem polega na tym, że dotyczy wszystkich istniejących formantów, jeśli utworzysz formant po tym wywołaniu, nie będzie miał nowej klasy.
LuisEduardoSP

27

Sposób SCSS dla podanego przykładu wyglądałby następująco:

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

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

Więcej informacji, sprawdź podstawy sassa


Jaka jest wartość dodana w porównaniu z tym? .composite,.something { display:inline }i.composite,.else { background:red }
Pavel Gatnar,

2
@PavelGatnar Możesz ponownie użyć definicji .somethingi .elseinnych definicji css.
Alter Lagos

15

Najlepsze, co możesz zrobić, to to

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

Nie zapomnij:

div.something.else {

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

}

1
nie szukam tego, ale było to dla mnie konstruktywne n__n
AgelessEssence

7

W pliku Css:

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

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

2
Więc co będzie wynikowe font-size?
abatishchev

Rozmiar czcionki wynosiłby 12px dla „p.Title”, ponieważ jest zdefiniowany po pierwszym w pliku. zastępuje pierwszy rozmiar czcionki.
YWE

@YWE: Czy to oznacza, że ​​deklaracje powinny być odwrotnie w porównaniu do tego, co jest napisane w tej odpowiedzi (przynajmniej jeśli chcemy przykładowo ilustrować)? Jeśli zwycięży ostatni zdefiniowany, to font-size: 16pxnigdy nie zadziała, prawda?
LUB Mapper

@ORMapper - zwykle dzieje się tak, że pierwsza deklaracja znajduje się we wspólnym pliku css, który jest wspólny dla wielu stron. Następnie druga deklaracja znajduje się w drugim pliku css, używanym tylko na niektórych stronach. I importowane po wspólnym pliku css. Dlatego te strony używają wartości „ostatnio widziany” 12px.
ToolmakerSteve

7

Zdaję sobie sprawę, że to pytanie jest teraz bardzo stare, ale tutaj nie ma nic!

Jeśli celem jest dodanie jednej klasy, która implikuje właściwości wielu klas, jako rozwiązanie natywne, poleciłbym użycie JavaScript / jQuery (jQuery nie jest tak naprawdę konieczne, ale na pewno przydatne)

Jeśli tak, na przykład .umbrellaClass„dziedziczy” .baseClass1i .baseClass2możesz mieć JavaScript, który uruchamia się w trybie gotowości.

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

Teraz wszystkie elementy .umbrellaClassbędą miały wszystkie właściwości obu .baseClasss. Należy pamiętać, że podobnie jak dziedziczenie OOP .umbrellaClassmoże, ale nie musi, mieć własne właściwości.

Jedynym zastrzeżeniem jest tutaj rozważenie, czy istnieją dynamicznie tworzone elementy, które nie będą istnieć podczas uruchamiania tego kodu, ale istnieją również proste sposoby obejścia tego.

Sucks css nie ma jednak natywnego dziedzictwa.


1
Takie podejście zostało już zaproponowane w @ DHoover za odpowiedź od 2013
Bryan

6

Idealny czas : przeszedłem od tego pytania do mojego e-maila, aby znaleźć artykuł o Less , bibliotece Ruby, która między innymi to robi:

Ponieważ super wygląda to tak footer, ale z inną czcionką, użyję techniki włączenia klasy Less (nazywają ją mixinem), aby powiedzieć jej, aby zawierała również te deklaracje:

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

Właśnie wtedy, gdy pomyślałem, że LESS nie może mnie więcej zaskoczyć ... Nie miałem pojęcia, że ​​możesz zaimportować formatowanie z innego bloku takiego jak ten. Świetna wskazówka.
Daniel Rippstein

4

Niestety CSS nie zapewnia „dziedziczenia” w sposób, w jaki robią to języki programowania, takie jak C ++, C # lub Java. Nie można zadeklarować klasy CSS, a następnie rozszerzyć ją o inną klasę CSS.

Możesz jednak zastosować więcej niż jedną klasę do znacznika w znacznikach ... w takim przypadku istnieje wyrafinowany zestaw reguł, które określają, które style zostaną zastosowane przez przeglądarkę.

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

CSS wyszuka wszystkie style, które można zastosować na podstawie tego, co znaczniki, i połączy style CSS z tych wielu reguł razem.

Zazwyczaj style są łączone, ale gdy pojawiają się konflikty, później zadeklarowany styl na ogół wygrywa (chyba że! Ważny atrybut jest określony w jednym ze stylów, w którym to przypadku wygrywa). Również style zastosowane bezpośrednio do elementu HTML mają pierwszeństwo przed stylami klas CSS.


Twoja odpowiedź pojawiła się jako pierwszy wynik w Google dla mnie i była pomocna. To powiedziawszy, mam dla ciebie wskazówkę - jeśli oferujesz rozwiązanie, najlepiej unikać negatywnego rozpoczynania zdań (niestety, CSS nie zapewnia dziedziczenia ...) Wiem, że każdy z odpowiednią cierpliwością czytałby, aby odkryć twoje fajne rozwiązanie ale czasem ludziom brakuje cierpliwości i może dojść do wniosku, że to, co próbują zrobić, jest niemożliwe. Aby uzyskać najlepszą szansę pomocy innym, możesz zacząć od czegoś takiego: „Chociaż CSS nie ma dziedziczenia, możesz osiągnąć to, czego potrzebujesz, do…”
egmfrs

4

Istnieje również SASS, który można znaleźć na stronie http://sass-lang.com/ . Istnieje tag @extend, a także system wprowadzania wtyczek. (Rubin)

To rodzaj konkurenta dla MNIEJ.


4

To nie jest możliwe w CSS.

Jedyną rzeczą obsługiwaną w CSS jest bycie bardziej szczegółowym niż inna reguła:

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

Rozpiętość z klasą „myclass” będzie miała obie właściwości.

Innym sposobem jest określenie dwóch klas:

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

Styl „else” zastąpi (lub doda) styl „czegoś”


Dla wszystkich stylów w 1 pliku istnieje rozwiązanie CSS podobne do dziedziczenia, patrz mój post.
Pavel Gatnar,

3

Możesz zastosować więcej niż jedną klasę CSS do elementu przez coś takiego jak ta klasa = „coś innego”


3

Jak powiedzieli inni, możesz dodać wiele klas do elementu.

Ale tak naprawdę nie o to chodzi. Dostaję twoje pytanie dotyczące dziedziczenia. Prawdziwe jest to, że dziedziczenie w CSS odbywa się nie poprzez klasy, ale poprzez hierarchie elementów. Aby modelować odziedziczone cechy, musisz zastosować je do różnych poziomów elementów w DOM.


Lepiej jest tworzyć podobne do dziedziczenia definicje CSS zamiast korzystać z całego łańcucha klas kompozycji, patrz mój post.
Pavel Gatnar,

2

Szukałem tego też jak szalonego i właśnie to rozgryzłem, próbując różnych rzeczy: P ... Cóż, możesz to zrobić w ten sposób:

composite.something, composite.else
{
    blblalba
}

Nagle zadziałało dla mnie :)


2

W szczególnych okolicznościach możesz wykonać „miękkie” dziedzictwo:

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

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

Działa to tylko wtedy, gdy dodajesz klasę .composite do elementu potomnego. Jest to „miękkie” dziedziczenie, ponieważ wszelkie wartości nieokreślone w .composite nie są dziedziczone w sposób oczywisty. Pamiętaj, że nadal byłoby mniej znaków, aby po prostu napisać „inline” i „red” zamiast „inherit”.

Oto lista właściwości i tego, czy robią to automatycznie: https://www.w3.org/TR/CSS21/propidx.html


2

Chociaż bezpośrednie dziedziczenie nie jest możliwe.

Możliwe jest użycie klasy (lub identyfikatora) dla znacznika nadrzędnego, a następnie użycie kombinacji CSS w celu zmiany zachowania znacznika potomnego z jego dziedziczności.

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>

Nie sugerowałbym używania tak wielu rozpiętości jak w przykładzie, jednak jest to tylko dowód koncepcji. Nadal istnieje wiele błędów, które mogą wystąpić podczas próby zastosowania CSS w ten sposób. (Na przykład zmiana typów dekoracji tekstowych).


2

Mniej i Sass to wstępne procesory CSS, które w cenny sposób rozszerzają język CSS. Tylko jedno z wielu ulepszeń, które oferują, to tylko opcja, której szukasz. Istnieje kilka bardzo dobrych odpowiedzi z Less i dodam rozwiązanie Sass.

Sass ma opcję rozszerzania, która pozwala na pełne rozszerzenie jednej klasy na inną. Więcej o rozszerzeniu można przeczytać w tym artykule



1

CSS tak naprawdę nie robi tego, o co prosisz. Jeśli chcesz pisać reguły z myślą o tym złożonym pomyśle, możesz sprawdzić kompas . Jest to struktura arkuszy stylów, która wygląda podobnie do wspomnianej już Less.

Pozwala robić miksy i wszystkie te dobre interesy.


Dodając więcej szczegółów do powyższego, Compass aka Sass robi poprzez Extend, PlaceHolders Mixins vs. Extend , bardziej szczegółowe informacje o PlaceHolders
Abhijeet

1

Dla tych, którzy nie są zadowoleni ze wspomnianych (doskonałych) postów, możesz użyć swoich umiejętności programistycznych, aby stworzyć zmienną (PHP lub dowolną inną) i przechowywać w niej wiele nazw klas.

To najlepszy hack, jaki mogłem wymyślić.

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

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

Następnie zastosuj zmienną globalną do pożądanego elementu, a nie do samych nazw klas

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


1

Nie myśl o klasach css jako klasach obiektowych, myśl o nich jako o narzędziu pośród innych selektorów do określania, które klasy atrybutów mają być stylowane w elemencie HTML. Pomyśl o wszystkim między nawiasami klamrowymi jak o klasie atrybutów , a selektory po lewej stronie informują elementy, które wybierają, aby dziedziczyć atrybuty z klasy atrybutów . Przykład:

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

Gdy element jest podany atrybut class="foo", warto pomyśleć o tym, jak nie dziedziczy atrybuty z klasy .foo, ale z atrybutem klasy A i klasy B atrybut . Tj. Wykres dziedziczenia ma głębokość jednego poziomu, a elementy pochodzą z klas atrybutów , a selektory określają, gdzie idą krawędzie, i określają pierwszeństwo, gdy istnieją konkurujące atrybuty (podobnie do kolejności rozwiązywania metod).

wprowadź opis zdjęcia tutaj

Praktyczne implikacje dla programowania są następujące. Załóżmy, że masz arkusz stylów podane powyżej, a chcesz dodać nową klasę .baz, gdzie powinien mieć takie same font-sizejak .foo. Naiwnym rozwiązaniem byłoby:

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

wprowadź opis zdjęcia tutaj

Za każdym razem, gdy muszę coś wpisać dwa razy, tak się wściekam! Nie tylko muszę to napisać dwa razy, ale teraz nie mam możliwości programowego wskazania tego .fooi .bazpowinienem mieć to samo font-size, i stworzyłem ukrytą zależność! Mój powyższy paradygmat sugeruje, że powinienem wyodrębnić font-sizeatrybut z klasy atrybutów 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 */}

wprowadź opis zdjęcia tutaj

Główny zarzut jest to, że teraz muszę wpisywać każdy z selektora atrybutu klasy A ponownie, aby określić, które elementy powinny wybrać powinien również dziedziczą atrybuty z klasy bazowej przyporządkowują . Nadal jednak trzeba pamiętać, aby edytować każdą klasę atrybutów, w której istnieją ukryte zależności za każdym razem, gdy coś się zmienia, lub korzystać z narzędzia innej firmy. Pierwsza opcja rozśmiesza boga, druga sprawia, że ​​chcę się zabić.


0

Jeśli chcesz mocniejszego preprocesora tekstu niż LESS, sprawdź PPWizard:

http://dennisbareis.com/ppwizard.htm

Ostrzeżenie: witryna jest naprawdę ohydna i ma małą krzywą uczenia się, ale jest idealna do tworzenia zarówno CSS, jak i kodu HTML za pomocą makr. Nigdy nie zrozumiałem, dlaczego więcej programistów internetowych tego nie używa.


11
Strona internetowa jest naprawdę ohydna.
nanofarad

Trochę ironii na stronie dla procesora HTML!
Ben Thurley

2
Tak, strona internetowa jest ohydna, ale to coś więcej. Trudno to odczytać i boli mnie też głowa!
ArtOfWarfare

1
Dobrze, że jest kompatybilny z Windows 3.1 na XP, lol
Alter Lagos

Dziwne niestandardowe narzędzie, nie tak.
berkus

-6

Możesz osiągnąć to, co chcesz, jeśli wstępnie przetworzysz pliki .css przez php. ...

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

...

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.