Як запобігти успадкуванню CSS?


94

У мене на бічній панелі є ієрархічне меню навігації, яке використовує вкладені списки (теги <ul> та <li>). Я використовую заздалегідь створену тему, яка вже має стилі для елементів списку, але я хочу змінити стиль для елементів верхнього рівня, але НЕ застосовувати її до підпунктів. Чи є простий спосіб застосувати стилі до тегу елемента списку верхнього рівня БЕЗ того, щоб ці стилі каскадувались до його дочірніх елементів списку? Я розумію, що можу явно додати переважні стилі до підпунктів, але я б дуже хотів уникати дублювання всього цього коду стилю, якщо є простий спосіб просто сказати "застосувати ці стилі до цього класу і НЕ каскадувати їх до будь-яких дочірніх елементів ". Ось html, який я використовую:

<ul id="sidebar">
  <li class="top-level-nav">
    <span>HEADING 1</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
  <li class="top-level-nav">
    <span>HEADING 2</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
</ul>

Отже, CSS має стилі для #sidebar ulі #sidebar ul liвже, але я хотів би додати додаткові стилі #sidebar .top-level-nav, які НЕ каскадуються до його під-дітей. Чи є спосіб зробити це просто, чи мені потрібно переставити всі стилі, щоб стилі, які були на #sidebar ulсьогодні, були специфічними для певних класів?


2
Я шукав подібні запитання на сайті і нічого не знайшов (не кажучи, що такого немає, але я все-таки подивився). Якщо ви знаєте, що це, не могли б ви, будь ласка, направити мене до цього? Дякую!

1
stackoverflow.com/questions/747308/breaking-css-inheritance | це майже говорить те, що відповів Метью.
JasonV

1
Отже, я вважаю, що відповідь: "ні, це неможливо зробити просто - вам потрібно вручну перевизначити кожен параметр стилю в підпункті" - я правильно це трактую? Знову дякую.

Відповіді:


38

На сьогодні ще немає батьківських селекторів (або, як їх називає Шон Інман , кваліфікованих селекторів ), тому вам доведеться застосовувати стилі до елементів дочірнього списку, щоб замінити стилі на батьківських елементах списку.

Каскадування - це свого роду вся суть каскадних таблиць стилів, звідси і назва.


13
Ця інформація застаріла з IE8. Дивіться відповідь Сільвіу Поставару. Будь ласка, подумайте про те, щоб змінити прапорець на більш відповідну відповідь.
tmuecksch

ха-ха, я згоден, що каскадування - це певна суть. Але повинен існувати спосіб зупинити розповсюдження від конкретного батька, який має бути іншим.
Обай Абд-Альгадер

72

Ви або використовуєте дочірній селектор

Так використовуючи

#parent > child

Тільки діти першого рівня зможуть застосовувати стилі. На жаль, IE6 не підтримує дочірній селектор.

В іншому випадку ви можете використовувати

#parent child child

Щоб встановити інші специфічні стилі для дітей, які перебувають нижче одного рівня.


1
Не могли б ви показати мені це в дії в JSFiddle? Я намагався відцентрувати вбудований блок, що відображається div, але він все одно центрує текст усередині div.
Calmarius

41

Існує властивість називається allв модулі CSS3 успадкування . Це працює так:

#sidebar ul li {
  all: initial;
}

Станом на 2016-12 рік, усі браузери, крім IE / Edge та Opera Mini, підтримують цю властивість.


4
@AndriusDobrotinas, щоб з часом отримати підтримку? Здається, я не повністю розумію ваш коментар. Існує плагін PostCSS, який надає цю функцію, якщо ви використовуєте PostCSS: github.com/maximkoretskiy/postcss-initial
Boldewyn

1
@AndriusDobrotinas, Ваш коментар дуже неконструктивний. Відповідь була розміщена заради спільноти; намагайтеся з усіх сил, щоб побачити його користь.
Коді

2
На сьогоднішній день лише IE та Opera Mini не підтримують це, усі інші основні браузери
Legends

@Boldewyn не має значення за замовчуванням, наскільки можна зрозуміти за пов'язаним документом w3 ...
benomatis

@webeno було, коли я писав відповідь: w3.org/TR/2013/WD-css3-cascade-20130103/#all-shorthand Здається, є деякі тонкі відмінності між старим defaultі новим unset, але зараз я ' у мене немає часу для подальшого розслідування. Не соромтеся редагувати відповідь, щоб оновити її.
Болдевін,

26

Ви можете використовувати селектор *, щоб повернути дочірні стилі до стандартних

приклад

#parent {
    white-space: pre-wrap;
}

#parent * {
    white-space: initial;
}

1
Це дуже гарне рішення - особливо, якщо ви не знаєте батьківського класу.
BurninLeo

Думаю, я знаю відповідь на це, але чи є спосіб все-таки встановити цей рядок? <div id="parent" style="white-space:pre-wrap;*white-space:initial;"/>
1,21 гігават

11

Обгортання iframe робить батьківський css застарілим.


2
Забавно, що це найгірша відповідь, оскільки технічно це єдиний фізичний спосіб зупинити успадкування CSS. Не те, що я стверджую, що ви повинні використовувати це таким чином.
davidelrizzo

2
Я б запропонував не отримувати фізичні дані за допомогою CSS, залишити його у віртуальному світі, де він належить!
michaelward82

Фактично додавання iframeзробило мій дочірній компонент невидимим. Думки?
Kevin Ghaboosi

5

Коротка відповідь: Ні, запобігти успадкуванню CSS неможливо. Ви можете замінити лише стилі, встановлені для батьків. Дивіться специфікацію:

Кожен елемент у документі HTML успадкує всі властивості, що успадковуються, від свого батька, за винятком кореневого елемента ( html), який не має батьківського елемента . - W3C

Окрім того, щоб замінити кожне успадковане майно. Ви також можете використовувати initialключове слово, наприклад color: initial;. Він також може використовуватися разом all, наприклад all: initial;, для скидання всіх властивостей одночасно. Приклад:

.container {
  color: blue;
  font-style: italic;
}
.initial {
  all: initial;
}
<div class="container">
  The quick brown <span class="initial">fox</span> jumps over the lazy dog
</div>

Таблиці підтримки браузера відповідно до Чи можу я використовувати ...

  • all (В даний час немає підтримки як в IE, так і в Edge, інші хороші)
  • initial (В даний час немає підтримки в IE, інші хороші)

Вам це може виявитися корисним, використовуючи в деяких випадках прямий дочірній селектор> . Приклад:

.list > li {
  border: 1px solid red;
  color: blue;
}
<ul class="list">
  <li>
    <span>HEADING 1</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
  <li>
    <span>HEADING 2</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
</ul>

Стиль межі застосовувався лише до безпосередніх дочірніх дітей <li>, оскільки borderце не успадкована властивість. Але колір тексту застосовано до всіх дітей, як colorі успадкована властивість.

Отже, >селектор був би корисний лише з не успадкованими властивостями, коли справа стосується запобігання успадкування.


2

Ви можете використовувати щось на зразок jQuery, щоб "вимкнути" цю поведінку, хоча я навряд чи вважаю це хорошим рішенням, оскільки ви отримуєте логіку відображення в css та javascript. Тим не менше, залежно від ваших вимог, ви можете виявити, що утиліти css jQuery полегшують вам життя, ніж пробування хакі-css, особливо якщо ви намагаєтеся змусити його працювати для IE6


2

Наприклад, якщо у вас є два div у документі XHTML.

<div id='div1'>
    <p>hello, how are you?</p>
    <div id='div2'>
        <p>I am fine, thank you.</p>
    </div>
</div>

Тоді спробуйте це в CSS.

#div1 > #div2 > p{
    color: red;
}

впливає лише на абзац "div2".

#div1 > p {
    color: red;
} 

впливає лише на абзац "div1".


2

Вам не потрібно посилання на клас для lis. Замість того, щоб мати CSS, як

li.top-level-nav { color:black; }

ти можеш писати

ul#sidebar > li { color:black; }

Це застосовуватиме стиль лише до lis, які відразу спускаються з бічної панелі ul.


0

просто поверніть їх за замовчуванням у селекторі "#sidebar ul li"


Дякую за відповідь. Так, я розумію, що можу повернути їх назад у стилі підпункту, але я намагаюся цього уникнути, оскільки використовую тему, яку я не створив, і мені цікаво, чи можу я заощадити купу часу просто використовуючи якесь правило "не-каскад: правда" або щось подібне, замість того, щоб знаходити всі різні стилі для ul і li, які розкидані повсюдно, а потім турбуватися про непередбачувані наслідки в інших областях сайту .
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.