Может ли класс CSS наследовать один или несколько других классов?


736

Я чувствую себя глупо из-за того, что так долго работал веб-программистом и не знал ответа на этот вопрос, я на самом деле надеюсь, что это возможно, и я просто не знал, а то, что я думаю, является ответом (а это то, что это невозможно) ,

Мой вопрос заключается в том, можно ли создать класс CSS, который «наследует» от другого класса CSS (или более одного).

Например, скажем, у нас было:

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

Я хотел бы сделать что-то вроде этого:

.composite 
{
   .something;
   .else
}

где класс .composite будет отображаться как встроенный и иметь красный фон


3
больше думать о каскадировании, чем о наследовании, здесь это не применимо
blu

Ответы:


427

Существуют такие инструменты, как LESS , которые позволяют вам создавать CSS на более высоком уровне абстракции, аналогично тому, что вы описываете.

Меньше называет эти "миксины"

Вместо

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

Ты мог бы сказать

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

#header {
  .rounded_corners;
}

#footer {
  .rounded_corners;
}

37
вау, LESS в значительной степени именно то, что я ищу ... обидно, что он изначально не поддерживается и написан на Ruby (я использую ASP.NET MVC)
Джоэль Мартинес,

1
Да, я тоже в мире ASP.NET, поэтому я не перенес его в свой рабочий процесс.
Ларсенал

Меньше - это красиво и заманчиво ... но я не очень успешно использовал его с CSSEdit в одном и том же рабочем процессе - поэтому я еще не полностью принял его.
Райан Флоренс

1
Да, МЕНЬШЕ довольно мило, не так ли? Я действительно работал над портом .NET здесь: nlesscss.codeplex.com .
Оуэн

77
в случае, если вы достигнете этого через Google: порт .Net теперь здесь
Eonasdan

310

Вы можете добавить несколько классов к одному элементу DOM, например

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

Правила, данные в более поздних классах (или более конкретные), переопределяют. Таким образом, fourthclassв этом примере вид преобладает.

Наследование не является частью стандарта CSS.


12
Знаете ли вы, какой класс преобладает, последние или первые, и безопасно ли поведение кросс-браузера? Допустим, у нас .firstClass {font-size:12px;} .secondClass {font-size:20px;}будет окончательный font-sizeвариант 12pxили 20pxэтот кроссбраузер безопасен?
Марко Демайо

27
Правило с самой высокой специфичностью в отношении селектора победит. Применяются стандартные правила специфичности; в вашем примере, поскольку «first» и «second» имеют одинаковую специфичность, правило, объявленное позже в CSS, победит.
Мэтт Бриджес

19
Мне нравится идея использовать чистый CSS (вместо LESS) для решения этой проблемы.
Alex

8
Мне также нравится идея не набирать несколько классов несколько раз - что является работой O (n ^ 2) :)
Secret

3
Что если я использую стороннюю библиотеку и хочу изменить дизайн / HTML, который она предоставляет, но не могу изменить встроенные CSS-файлы в этой библиотеке? Там мне нужно какое-то наследование в классах CSS.
Шивам

112

Да, но не совсем с этим синтаксисом.

.composite,
.something { display:inline }

.composite,
.else      { background:red }

7
Это отстой, но я рад, что у нас по крайней мере есть это!
Pacerier

3
Почему это отстой? это кажется очень хорошим Я не могу понять разницу между символом запятой и решением less.js.
Реви

21
Потому что, если классы .something и .else находятся в разных файлах и вы не можете их изменить, значит, вы застряли.
Александр Мелар

8
Это был правильный ответ, потому что он ответил на вопрос, используя чистый синтаксис CSS. Тем не менее, ответ лучше знать.
Раддевус

1
Это должен быть исключенный ответ.
eaglei22

66

Держите ваши общие атрибуты вместе и назначьте определенные (или переопределите) атрибуты снова.

/*  ------------------------------------------------------------------------------ */   
/*  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
Это очень близко к идеальному решению, я надеюсь, что люди не откажутся от него только потому, что у него мало голосов. Фактически, одна из самых сложных проблем «наследования CSS» заключается в том, что вы обычно получаете уже сделанное, огромное веб-программное обеспечение (например, программное обеспечение для электронной коммерции или блог, известное PHP), и они используют PHP-код, который изначально выиграл » добавить несколько классов к элементам HTML, которые они превзошли. Это заставляет вас ходить по кругу и связываться с исходным кодом (теряя изменения, если вы обновитесь позже), чтобы заставить его выводить эти дополнительные классы. При таком подходе вы редактируете только CSS-файл!
Дарио Фумагалли

3
Это было именно то, что я искал. Не стоит ли этот же подход работать с CSS-селекторами? Вместо того, чтобы указать, h1, h2, etcвы могли бы указать.selector1, .selector2, .etc
JeffryHouser

Я хотел бы прокомментировать, что именно этот подход w3 использовал в своей рекомендуемой стандартной таблице стилей html: [w3 CSS2]: w3.org/TR/CSS2/sample.html . Я также пытаюсь понять, как организовать код CSS, и кажется, что парадигма инвертирована по сравнению с типичным объектно-ориентированным наследованием: вы используете классы (или, в более общем случае, селекторы), чтобы указать, какие элементы наследуют какие атрибуты, но вы наследуете атрибуты (по крайней мере, именно так иерархия может наиболее легко существовать логически), а затем при необходимости переопределяете атрибуты на более конкретные селекторы.
Натан Чаппелл

51

Элемент может принимать несколько классов:

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

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

И это примерно так близко, как вы собираетесь получить, к сожалению. Я хотел бы видеть эту особенность, наряду с псевдонимами класса когда-нибудь.


45

Нет, ты не можешь сделать что-то вроде

.composite 
{
   .something;
   .else
}

Это не «классовые» имена в ОО-смысле. .somethingи .elseпросто селекторы не более того.

Но вы можете указать два класса для элемента

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

или вы можете посмотреть в другую форму наследования

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

Где цвет фона и абзацы унаследованы от настроек во вложенном div, который .fooстилизован. Возможно, вам придется проверить точную спецификацию W3C. inheritпо умолчанию для большинства свойств, но не для всех.


1
да, это (первая часть) было моим ожиданием, когда я впервые услышал о CSS еще в 20-м веке ... и у нас все еще его нет, они сжигают производительность на некоторых динамических вещах, в то время как это может быть статически скомпоновано непосредственно перед применением CSS и он заменяет потребность в переменных (статические «переменные»)
neu-rah

30

Я столкнулся с этой же проблемой и в итоге использовал решение JQuery, чтобы создать впечатление, что класс может наследовать другие классы.

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

Это найдет все элементы с классом «составной» и добавит классы «что-то» и «еще» к элементам. Так что-то вроде <div class="composite">...</div>будет в итоге так:
<div class="composite something else">...</div>


1
Проблема этого решения заключается в том, что он применяется ко всем существующим элементам управления. Если вы создадите элемент управления после этого вызова, у него не будет нового класса.
LuisEduardoSP

27

Способ SCSS для данного примера будет примерно таким:

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

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

Больше информации, проверьте основы Sass


Какова добавленная стоимость по сравнению с этим? .composite,.something { display:inline }и.composite,.else { background:red }
Павел Гатнар

2
@PavelGatnar Вы можете повторно использовать определения .somethingи .elseв других определениях CSS.
Альтер Лагос,

16

Лучшее, что вы можете сделать, это

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>


7

В Css файле:

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

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

2
Так что будет в результате font-size?
Абатищев

Размер шрифта будет 12px для «p.Title», потому что он определен после первого в файле. он переопределяет первый размер шрифта.
YWE

@YWE: Значит ли это, что декларации должны быть наоборот, по сравнению с тем, что написано в этом ответе (по крайней мере, если мы хотим, чтобы пример был иллюстративным)? Если преобладает последний определенный, то font-size: 16pxникогда не вступит в силу, верно?
ИЛИ Mapper

@ORMapper - обычно получается, что первое объявление находится в общем CSS-файле, который используется несколькими страницами. Затем второе объявление находится во втором CSS-файле и используется только на определенных страницах. И импортируется после общего файла CSS. Таким образом, эти страницы используют значение «последний раз видел» 12px.
ToolmakerSteve

7

Я понимаю, что этот вопрос сейчас очень старый, но здесь нет ничего!

Если намерение состоит в том, чтобы добавить один класс, который подразумевает свойства нескольких классов, в качестве нативного решения, я бы рекомендовал использовать JavaScript / jQuery (jQuery на самом деле не нужен, но, безусловно, полезен)

Если у вас есть, например, .umbrellaClassчто «наследует» от, .baseClass1и .baseClass2вы могли бы иметь некоторый JavaScript, который запускается готовым.

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

Теперь все элементы .umbrellaClassбудут иметь все свойства обоих .baseClasss. Обратите внимание, что, как ООП наследование,.umbrellaClass может иметь или не иметь свои собственные свойства.

Единственное предостережение здесь заключается в том, чтобы рассмотреть, существуют ли динамически создаваемые элементы, которые не будут существовать, когда этот код запускается, но есть и простые способы обойти это.

Отстой CSS не имеет наследства, хотя.


1
Этот подход уже был предложен в @ DHoover в ответ с 2013 года
Bryan

6

Идеальное время : я перешел от этого вопроса к своей электронной почте, чтобы найти статью о Less , библиотеке Ruby, которая, помимо прочего, делает это:

Поскольку super выглядит так же footer, но с другим шрифтом, я буду использовать технику включения класса Less (они называют это mixin), чтобы сказать, чтобы она также включала эти объявления:

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

Просто когда я подумал, что LESS не сможет меня больше удивить ... Я понятия не имел, что вы можете импортировать форматирование из другого блока, подобного этому. Отличный совет.
Даниэль Риппштейн

4

К сожалению, CSS не обеспечивает «наследование» так, как это делают языки программирования, такие как C ++, C # или Java. Вы не можете объявить класс CSS, а затем расширить его другим классом CSS.

Тем не менее, вы можете применить более одного класса к тегу в вашей разметке ... в этом случае существует сложный набор правил, которые определяют, какие фактические стили будут применяться браузером.

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

CSS будет искать все стили, которые могут быть применены на основе вашей разметки, и объединять стили CSS из этих нескольких правил вместе.

Как правило, стили объединяются, но когда возникают конфликты, позднее объявленный стиль обычно побеждает (если только атрибут! Important не указан в одном из стилей, в этом случае выигрывает). Кроме того, стили, применяемые непосредственно к элементу HTML, имеют приоритет над стилями классов CSS.


Ваш ответ появился в Google как первый результат и оказался полезным. Тем не менее, у меня есть совет для вас - если вы предлагаете решение, лучше избегать отрицательного начала предложений (К сожалению, CSS не обеспечивает наследования ..) Я знаю, что любой, у кого есть терпение, будет читать дальше, чтобы найти ваше хорошее решение. но иногда людям не хватает терпения, и они могут прийти к выводу, что то, что они пытаются сделать, невозможно. Чтобы получить максимальную возможность помогать другим, вы можете начать с чего-то вроде «Хотя у CSS нет наследования, вы можете достичь того, что вам нужно, с помощью ...»
egmfrs

4

Также есть SASS, который вы можете найти на http://sass-lang.com/ . Там есть тег @extend, а также система смешанных типов. (Рубин)

Это своего рода конкурент LESS.


4

Это невозможно в CSS.

Единственное, что поддерживается в CSS, это быть более конкретным, чем другое правило:

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

Пролет с классом «myclass» будет иметь оба свойства.

Другой способ - указать два класса:

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

Стиль «else» переопределяет (или добавляет) стиль «что-то»


Для всех стилей в 1 файле есть решение, похожее на наследование в CSS, см. Мой пост.
Павел Гатнар

3

Вы можете применить более одного класса CSS к элементу с помощью чего-то вроде этого класса = "что-то еще"


3

Как уже говорили другие, вы можете добавить несколько классов к элементу.

Но дело не в этом. Я получил ваш вопрос о наследовании. Суть в том, что наследование в CSS осуществляется не через классы, а через иерархии элементов. Поэтому для моделирования унаследованных черт вам необходимо применять их к различным уровням элементов в DOM.


Лучше создавать CSS-определения, подобные наследованию, а не использовать всю цепочку классов композиции, см. Мой пост.
Павел Гатнар

2

Я искал это как сумасшедший, и я просто понял это, попробовав разные вещи: P ... Ну, вы можете сделать это так:

composite.something, composite.else
{
    blblalba
}

У меня вдруг сработало :)


2

В определенных обстоятельствах вы можете сделать «мягкое» наследование:

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

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

Это работает, только если вы добавляете класс .composite к дочернему элементу. Это «мягкое» наследование, потому что любые значения, не указанные в .composite, явно не наследуются. Имейте в виду, что все равно будет меньше символов, чтобы просто написать «встроенный» и «красный» вместо «наследовать».

Вот список свойств и независимо от того, делают ли они это автоматически: https://www.w3.org/TR/CSS21/propidx.html


2

Пока прямое наследование невозможно.

Можно использовать класс (или идентификатор) для родительского тега, а затем использовать CSS-комбинаторы, чтобы изменить поведение дочернего тега из его иерархии.

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>

Я бы не советовал использовать столько пролетов, как в примере, но это всего лишь доказательство концепции. Все еще есть много ошибок, которые могут возникнуть при попытке применить CSS таким способом. (Например, изменение типов оформления текста).


2

Less и Sass - это препроцессоры CSS, которые ценным образом расширяют язык CSS. Только одно из многих улучшений, которые они предлагают, это просто вариант, который вы ищете. Есть несколько очень хороших ответов с Less, и я добавлю решение Sass.

У Sass есть опция расширения, которая позволяет полностью расширить один класс на другой. Подробнее о расширении вы можете прочитать в этой статье



1

CSS на самом деле не делает то, что вы просите. Если вы хотите написать правила с учетом этой составной идеи, вы можете проверить компас . Это фреймворк таблиц стилей, который похож на уже упомянутый Less.

Это позволяет вам делать миксины и все такое хорошее дело.


Добавляя больше деталей к вышеупомянутому, Compass aka Sass делает через Extend, PlaceHolders Mixins vs Extend , более подробную информацию о PlaceHolders
Abhijeet

1

Для тех, кто не удовлетворен упомянутыми (отличными) постами, вы можете использовать свои навыки программирования, чтобы создать переменную (PHP или любую другую) и сохранить в ней несколько имен классов.

Это лучший взлом, который я мог придумать.

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

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

Затем примените глобальную переменную к желаемому элементу, а не к именам классов.

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


1

Не думайте о классах CSS как об объектно-ориентированных классах, думайте о них как об инструменте среди других селекторов, чтобы указать, к каким классам атрибутов применяется элемент html. Подумайте обо всем, что между фигурными скобками, как о классе атрибутов , а селекторы слева говорят элементам, которые они выбирают для наследования атрибутов из класса атрибутов . Пример:

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

Когда элемент получает атрибут class="foo", полезно думать об этом не как наследование атрибутов из класса .foo, но из атрибута класса А и класса B атрибут . Т.е. граф наследования имеет один уровень вглубь, элементы выводятся из классов атрибутов , а селекторы указывают, куда идут ребра, и определяют приоритет при наличии конкурирующих атрибутов (аналогично порядку разрешения метода).

введите описание изображения здесь

Практическое значение для программирования заключается в следующем. Допустим, у вас есть таблица стилей, приведенная выше, и вы хотите добавить новый класс .baz, где он должен быть таким же, font-sizeкак и .foo. Наивное решение было бы так:

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

введите описание изображения здесь

Каждый раз, когда мне приходится что-то печатать дважды, я так злюсь! Мало того, что я должен написать это дважды, теперь у меня нет возможности программно указать, что .fooи .bazдолжно иметь то же самое font-size, и я создал скрытую зависимость! Моя вышеприведенная парадигма предполагает, что я должен абстрагировать font-sizeатрибут от класса атрибута 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 */}

введите описание изображения здесь

Основная жалоба здесь является то , что теперь я должен перепечатывать каждый селектор из атрибута класса A еще раз , чтобы указать , что элементы , они должны выбрать также должны наследовать атрибуты из атрибутов базового класса A . Тем не менее, альтернативы заключаются в том, чтобы не забывать редактировать каждый класс атрибутов, где есть скрытые зависимости каждый раз, когда что-то меняется, или использовать сторонний инструмент. Первый вариант заставляет бога смеяться, второй заставляет меня хотеть убить себя.


0

Если вам нужен более мощный текстовый препроцессор, чем LESS, проверьте PPWizard:

http://dennisbareis.com/ppwizard.htm

Предупреждение, что веб-сайт действительно отвратителен и имеет небольшую кривую обучения, но он идеально подходит для создания как CSS, так и HTML кода с помощью макросов. Я никогда не понимал, почему больше веб-кодеров не используют его.


11
Сайт является действительно отвратительным.
нанофарад

Какая ирония на сайте для HTML-процессора!
Бен Терли

2
Да, сайт отвратительный, но это больше, чем просто. Трудно читать, и у меня тоже болит голова!
ArtOfWarfare

1
Хорошо, что он совместим с Windows 3.1 до XP, смеется
Alter Lagos

Странный нестандартный инструмент, не похожий.
Беркус

-6

Вы можете достичь того, чего хотите, если предварительно обработаете свои файлы .css через php. ...

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

...

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.