Использование тегов <style> в <body> с другим HTML-кодом

<html>
  <body>
    <style type="text/css">
      p.first {color:blue}
      p.second {color:green}
    </style>

    <p class="first">Hello World</p>
    <p class="second">Hello World</p>

    <style type="text/css">
      p.first {color:green}
      p.second {color:blue}
    </style>

    <p class="first">Hello World</p>
    <p class="second">Hello World</p>
  </body>
</html>

Как браузер должен отображать css, который не соприкасается? Предполагается ли он генерировать некоторую структуру данных, используя все стили css на странице и использовать их для рендеринга?

Или он визуализирует информацию о стиле в том порядке, в котором он видит?

Ответ 1

Как уже упоминали другие, HTML 4 требует размещения <style> в разделе <head> (хотя большинство браузеров допускают использование тегов <style> внутри body).

Однако HTML 5 содержит атрибут scoped (см. Обновление ниже), который позволяет создавать таблицы стилей, которые находятся в родительском элементе <style>. Это также позволяет размещать теги <style> внутри элемента <body>:

<!DOCTYPE html>
<html>
<head></head>
<body>

<div id="scoped-content">
    <style type="text/css" scoped>
        h1 { color: red; } 
    </style>

    <h1>Hello</h1>
</div>

    <h1>
      World
    </h1>

</body>
</html>

Если вы отобразите приведенный выше код в браузере с поддержкой HTML-5, который поддерживает scoped, вы увидите ограниченную область применения таблицы стилей.

Там только одна главная оговорка...

На момент написания этого ответа (май 2013 г.) практически ни один из популярных браузеров в настоящее время не поддерживает атрибут scoped. (Хотя, очевидно, сборки Chromium для разработчиков поддерживают его.)

ОДНАКО, есть интересное следствие атрибута scoped который относится к этому вопросу. Это означает, что будущие браузеры получают мандат через стандарт, чтобы разрешить элементы <style> внутри <body> (при условии, что элементы <style> ограничены).

Итак, учитывая, что:

  • Почти каждый существующий браузер в настоящее время игнорирует атрибут scoped
  • Почти каждый существующий браузер в настоящее время допускает теги <style> внутри <body>
  • В будущих реализациях потребуется разрешить (ограничить) теги <style> внутри <body>

... тогда размещение тегов <style> внутри тела буквально не повредит *, если вы будете проверять их в будущем с помощью атрибута scoped. Единственная проблема заключается в том, что современные браузеры не будут на самом деле ограничивать область применения таблицы стилей - они будут применять ее ко всему документу. Но дело в том, что для практических целей вы можете включать теги <style> в <body> при условии, что вы:

  • Перспективный HTML, включив атрибут scoped
  • Поймите, что на данный момент таблица стилей внутри <body> фактически не будет ограничена (поскольку пока еще не поддерживается основная браузерная поддержка)


* кроме, конечно, для того, чтобы разозлить валидаторы HTML...


Наконец, что касается общего (но субъективного) утверждения о том, что встраивание CSS в HTML является плохой практикой, следует отметить, что весь смысл атрибута scoped состоит в том, чтобы приспособить типичные современные среды разработки, которые позволяют разработчикам импортировать куски HTML в виде модулей или синдицированных содержание. Очень удобно иметь встроенный CSS, который применяется только к определенному фрагменту HTML, чтобы разрабатывать инкапсулированные, модульные компоненты со специфическими стилями.


Обновление по состоянию на февраль 2019 г., согласно документации Mozilla, атрибут scoped устарел. Chrome прекратил поддерживать его в версии 36 (2014) и Firefox в версии 62 (2018). В обоих случаях эта функция должна была быть явно включена пользователем в настройках браузера. Ни один другой крупный браузер никогда не поддерживал его.

Ответ 2

BREAKING BAD NEWS для любителей стиля в теле: W3C недавно проиграл HTML-войну против WHATWG, чей безлицензионный HTML "Living Standard" теперь стал официальным, что, увы, не позволяет использовать STYLE в BODY. Недолгие счастливые дни закончились. ;) Валидатор W3C также работает по спецификациям WHATWG. (Спасибо @FrankConijn за хедз-ап!)

(Примечание: в данном случае это "на сегодняшний день", но, поскольку нет контроля версий, ссылки могут стать недействительными в любой момент без уведомления или контроля. Если вы не хотите ссылаться на его отдельные исходные коммиты на GitHub, вы в основном не можете Дольше делайте стабильные ссылки на новый официальный стандарт HTML AFAIK. Пожалуйста, исправьте меня, если есть канонический способ сделать это правильно.)

СОБСТВЕННЫЕ ХОРОШИЕ НОВОСТИ:

Да, STYLE наконец-то действует в BODY, начиная с HTML5.2!scoped ушел тоже.)

Из спецификации W3C (смакуйте последнюю строчку!):

4.2.6. Элемент стиля

...

Контексты, в которых этот элемент может быть использован:

Где ожидается содержание метаданных.

В элементе noscript, который является дочерним элементом элемента head.

В теле, где ожидается поток содержимого.


META SIDE-NOTE:

Сам факт того, что, несмотря на убытки от "войны браузеров", нам все равно приходилось продолжать разработку против двух смехотворно конкурирующих "официальных" стандартов HTML (кавычки для 1 standard + 1 standard < 1 standard) означает, что "отступление к подход к веб-разработке, основанный на здравом смысле, никогда не переставал применяться.

Это может, наконец, измениться сейчас, но, ссылаясь на общепринятую точку зрения: веб-разработчики/разработчики и, следовательно, браузеры, в свою очередь, должны в конечном итоге решить, что должно (и не должно) быть в спецификациях, когда нет веских оснований для того, что уже было сделано в реальность. И большинство браузеров долгое время поддерживали STYLE в BODY (так или иначе; см., Например, scoped attp.), Несмотря на присущую ему производительность (и, возможно, другие) штрафы (которые мы должны решить платить или нет, а не спецификации). Так, например, я буду продолжать делать ставки на них, и не собираюсь терять надежду. ;) Если WHATWG уважает реальность/авторов так, как они утверждают, они могут просто сделать здесь то, что сделал W3C.

Ответ 3

Когда я вижу, что системы управления контентом на больших сайтах обычно добавляют некоторый стиль <style> элементы (некоторые, не все), близкие к содержанию, которое полагается на эти классы, я делаю вывод, что лошадь вышла из сарая.

Посмотрите на источники страниц cnn.com, nytimes.com, huffingtonpost.com, ближайшую газету большого города и т.д. Все они делают это.

Если есть веская причина добавить дополнительный <style> где-то в теле - например, если вы включаете() различные и независимые элементы страницы в реальном времени, и каждый из них имеет встроенный стиль <style> и организация будет более чистой, более модульной, понятной и удобной, я говорю, просто кусаю пулю. Конечно, было бы лучше, если бы мы могли иметь "локальный" стиль с ограниченной областью действия, например, локальные переменные, но вы идете работать с HTML, который у вас есть, а не с HTML, который вы, возможно, захотите или хотите иметь в более позднее время.

Конечно, существуют потенциальные недостатки и хорошие (хотя и не всегда убедительные) причины следовать ортодоксии, как это выяснили другие. Но для меня это все больше похоже на продуманное использование <style> в <body> уже перешел в основное русло.

Ответ 4

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

Протестировано в последних версиях FF и Google Chrome в Fedora, а также в FF, Opera, IE и Chrome под XP.

Ответ 5

Тег <style> принадлежит разделу <head>, отделенному от всего содержимого.

Ссылки: Спецификации W3C и W3Schools

Ответ 6

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

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

В любом случае это недействительный HTML, поэтому я бы сказал, что это бессмысленно думать. Теги <style> относятся к разделу head страницы.

Ответ 7

Как говорили другие, это недействительно html, поскольку теги стиля принадлежат в голове.

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

Ответ 8

В вашем примере браузер не "должен" делать что-либо. HTML недопустим. Вызывается либо восстановление с ошибкой, либо парсер делает это как есть.

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

Ответ 9

Поскольку это HTML недействительно, он не влияет на результат... это просто означает, что HTML придерживается стандарта (только для организационных целей). Ради действительности это могло быть написано следующим образом:

<html>
<head>
<style type="text/css">
  p.first {color:blue}
  p.second {color:green}
</style>
</head>
<body>
<p class="first" style="color:green;">Hello World</p>
<p class="second" style="color:blue;">Hello World</p>

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

Ответ 10

Я предполагаю, что это может быть проблемой ограниченного контекста, например, редакторов WYIWYG в веб-системе, используемой пользователями, не являющимися программистами, что ограничивает возможности соблюдения стандартов. Иногда (например, TinyMCE) это библиотека, которая помещает ваш контент/код в тег textarea, который редактором представляется как большой тег div. И иногда это может быть старая версия этих редакторов.

Я полагаю, что:

  1. эти пользователи, не являющиеся программистами, не имеют открытого канала с системными администраторами (или веб-сайтами учреждений), чтобы попросить включить некоторые правила CSS в системные stylesheets. На самом деле, это было бы нецелесообразно для администраторов (или веб-разработчиков), учитывая количество запросов в том смысле, что они будут иметь.
  2. эта система является устаревшей и до сих пор не поддерживает более новые версии HTML.

В некоторых случаях, без использования style правил, это может быть очень плохим опытом проектирования. Так что да, эти пользователи нуждаются в настройке. Хорошо, но каковы будут решения в этом сценарии? Учитывая различные способы вставки CSS в html страницу, я предполагаю, что эти решения:


1-й вариант: спросите своего сисадма

Попросите вашу систему adm для включения некоторых правил CSS в системные stylesheets. Это будет внешнее или внутреннее решение CSS. Как уже говорилось, это может быть невозможно.


2-й вариант: <link> на <body>

Используйте внешнюю таблицу стилей для тега body, т.е. Используйте тег link внутри области, к которой у вас есть доступ (то есть на сайте, внутри тега body а не в теге head). Некоторые источники говорят, что это нормально, но "не очень хорошая практика", как MDN:

Элемент <link> может встречаться в элементе <head> или <body>, в зависимости от того, имеет ли он тип ссылки body-ok. Например, тип ссылки stylesheet - body-ok, и поэтому в теле допускается <link rel="stylesheet">. Тем не менее, это не очень хорошая практика для подражания; имеет больше смысла отделять ваши элементы <link> от содержимого вашего тела, помещая их в <head>.

Некоторые другие ограничивают его разделом <head>, например, w3schools:

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

тестирование

Я проверил это здесь (окружение рабочего стола, в браузере), и оно работает для меня. Создайте файл foo.html:

<!DOCTYPE html>
<html>
<head></head>
<body>
    <link href="bar.css" type="text/css" rel="stylesheet">
    <h1 class="test1">Hello</h1>
    <h1 class="test2">World</h1>
</body>
</html>

И затем CSS файл в том же каталоге с именем bar.css:

.test1 { 
    color: green;
};

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


3-й вариант: <style> на <body>

Используйте интернет-таблицу стилей для тега body, т.е. Используйте тег style внутри области, к которой у вас есть доступ (то есть на сайте, внутри тега body а не в теге head). Это то, что Чарльз Сальвия и Sz ответы здесь. Выбирая этот вариант, учитывайте их опасения.


4-й, 5-й и 6-й варианты: JS способы

Оповещение Это относится к изменению элемента <head> страницы. Может быть, этого не допустят системные администраторы учреждения. Поэтому рекомендуется сначала спросить их разрешение.

Хорошо, если разрешение предоставлено, стратегия заключается в доступе к <head>. Как? Методы JavaScript.

4-й вариант: новый <link> на <head>

Это еще одна версия 2-го варианта. Используйте внешнюю таблицу стилей для <head>, т.е. Используйте элемент <link> вне области, к которой у вас есть доступ (то есть на сайте, а не внутри тега body и да внутри тега head). Это решение соответствует рекомендациям MDN и w3schools, как указано выше, по второму варианту решения. Новый объект Link будет создан.

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

тестирование

Я проверил это здесь (окружение рабочего стола, в браузере), и оно работает для меня. Создайте файл f.html:

<!DOCTYPE html>
<html>
<head></head>
<body>
    <h1 class="test1">Hello</h1>
    <h1 class="test2">World</h1>
    <script>
        // JS code here
    </script>
</body>
</html>

Внутри тега script:

var newLink = document.createElement("link");
newLink.href = "bar.css";
newLink.rel = "stylesheet";
newLink.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(newLink);

И затем в файле CSS, в том же каталоге, называемом bar.css (как во втором варианте):

.test1 { 
    color: green;
};

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

5-й вариант: новый <style> на <head>

Используйте новую внутреннюю таблицу стилей для <head>, т.е. Используйте новый элемент <style> вне области, к которой у вас есть доступ (то есть на сайте, а не внутри тега body и yes внутри тега head). Новый объект Style будет создан.

Это решается через JS. Один простой способ демонстрируется следующим.

тестирование

Я проверил это здесь (окружение рабочего стола, в браузере), и оно работает для меня. Создайте файл foobar.html:

<!DOCTYPE html>
<html>
<head></head>
<body>
    <h1 class="test1">Hello</h1>
    <h1 class="test2">World</h1>
    <script>
        // JS code here
    </script>
</body>
</html>

Внутри тега script:

var newStyle = document.createElement("style");
newStyle.innerHTML = 
    "h1.test1 {"+
        "color: green;"+
    "}";
document.getElementsByTagName("head")[0].appendChild(newStyle);

6-й вариант: использование существующего <style> в <head>

Использовать существующую внутреннюю таблицу стилей для <head>, т.е. Использовать элемент <style> вне области, к которой у вас есть доступ (то есть на сайте, а не внутри тега body и yes внутри тега head), если некоторые существуют. Будет создан новый объект Style или будет использован объект CSSStyleSheet (в принятом здесь коде решения).

Это в какой-то момент рискованно. Во-первых, потому что может не существовать некоторый объект <style>. В зависимости от способа реализации этого решения, вы можете получить undefined возврат (система может использовать внешнюю таблицу стилей). Во-вторых, потому что вы будете редактировать дизайн системы авторской работы (вопросы авторства). В-третьих, потому что это не может быть разрешено в вашем учреждении ИТ-политики безопасности. Поэтому попросите разрешения сделать это (как в других решениях JS).

Предположим, опять же, разрешение было предоставлено:

Вам нужно будет учесть некоторые ограничения метода, доступного для этого способа: insertRule(). Предлагаемое решение использует сценарий по умолчанию и операцию с первой stylesheet, если таковая существует.

тестирование

Я проверил это здесь (окружение рабочего стола, в браузере), и оно работает для меня. Создайте файл foo_bar.html:

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <h1 class="test1">Hello</h1>
    <h1 class="test2">World</h1>
    <script>
      // JS code here
    </script>
  </body>
</html>

Внутри тега script:

function demoLoop(){ // remove this line
    var elmnt = document.getElementsByTagName("style");
    if (elmnt.length === 0) {
        // there isn't style objects, so it more interesting create one
        var newStyle = document.createElement("style");
        newStyle.innerHTML =
            "h1.test1 {" +
                "color: green;" +
            "}";
        document.getElementsByTagName("head")[0].appendChild(newStyle);
    } else {
        // Using CSSStyleSheet interface
        var firstCSS = document.styleSheets[0];
        firstCSS.insertRule("h1.test2{color:blue;}"); // at this way (without index specified), will be like an Array unshift() method
    }
} // remove this too
demoLoop(); // remove this too
demoLoop(); // remove this too

Еще один подход к этому решению - использование объекта CSSStyleDeclaration (документы в w3schools и MDN). Но это может быть неинтересно, учитывая риск переопределения существующих правил в системе CSS.


7-й вариант: встроенный CSS

Используйте встроенный CSS. Это решает проблему, хотя в зависимости от размера страницы (в строках кода) поддержание (самим автором или другим назначенным лицом) кода может быть очень трудным.

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

тестирование

Создайте файл _foobar.html:

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <h1 style="color: green;">Hello</h1>
    <h1 style="color: blue;">World</h1>    
  </body>
</html>

Отвечая строго на вопрос, заданный Гаганом

Как браузер должен отображать CSS, который не является смежным?

  1. Предполагается ли создать некоторую структуру данных, используя все стили CSS на странице, и использовать ее для рендеринга?
  2. Или он отображает информацию о стиле в том порядке, в котором он видит?

(цитата адаптирована)

Для более точного ответа я предлагаю Google эти статьи:

  • Как работают браузеры: за кулисами современных веб-браузеров
  • Render-Tree Строительство, макет и краски
  • Что значит "визуализировать" веб-страницу?
  • Как работает рендеринг в браузере - негласно
  • Рендеринг - Стандарт HTML
  • 10 рендеринга - HTML5