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

736

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

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

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

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

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

.composite 
{
   .something;
   .else
}

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

Джоэл Мартинес
источник
3
больше думать о каскадировании, чем о наследовании, здесь это не применимо
blu
1
Потрясающие!! haacked.com/archive/2009/12/02/t4-template-for-less-css.aspx
Джоэль Мартинес

Ответы:

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;
}
Larsenal
источник
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 }
mlouro
источник
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;
}
user2990362
источник
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>

DHoover
источник
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>
electricalbah
источник
12

Не забывайте:

div.something.else {

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

}
Райан Флоренс
источник
1
я не ищу это, но это было конструктивно для меня n__n
AgelessEssence
7

В Css файле:

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

p.SubTitle p.Title
{
   font-size: 12px;
}
pedrofernandes
источник
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;
}
RichieHindle
источник
Просто когда я подумал, что LESS не сможет меня больше удивить ... Я понятия не имел, что вы можете импортировать форматирование из другого блока, подобного этому. Отличный совет.
Даниэль Риппштейн
4

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

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

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

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

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

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

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

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

chug2k
источник
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
}

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

BiBi
источник
2

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

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

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

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

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

hydrix
источник
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 таким способом. (Например, изменение типов оформления текста).

Stryderunknown
источник
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 кода с помощью макросов. Я никогда не понимал, почему больше веб-кодеров не используют его.

BloDoe
источник
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 '}';

...

Джон
источник