他のHTMLで<body>の<style>タグを使用する


195
<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スタイルを使用してデータ構造を生成し、それをレンダリングに使用することになっていますか?

それとも、表示される順序でスタイル情報を使用してレンダリングしますか?


2
これは有効なHTMLではないため、未定義の動作です。有効な要素と無効な要素の詳細については、en.wikipedia.org
Felix Kling

2
さておき、この問題を置く、アップミックスする悪い習慣であるCSSHTML
0x2D9A3

1
@ 0x2D9A3必ずしも正しいとは限りません。<head>タグで定義されているCSSよりも外部CSSページのリクエストに時間がかかる
Kolob Canyon

@KolobCanyon同意しますが、原則として、CSSは別のファイルにする必要があります。CSSが大量にある場合、管理(保守、(後)処理、縮小、バンドル)と別のファイルとして機能することの両方が簡単であり、コンテンツ(HTML)の読み込みも高速になり、UXが向上する可能性があります。ただし、常に開発と同様に、すべてがコンテキスト固有であるため、YMMW :)
0x2D9A3

3
@KolobCanyon、これはCSSが別のファイルにあるべきかどうかの問題ではありません。この場合の問題は、<body>ではなくのCSSについて<head>です。
レイバターワース

回答:


312

他の人がすでに述べたように、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と、スタイルシートのスコープが制限されます。

重要な警告が1つだけあります...

この回答を書いている時点(2013年5月)では、現在このscoped属性をサポートしている主流のブラウザーはほとんどありません。(明らかに、Chromiumの開発者ビルドはそれをサポートしています。)

ただし、scopedこの質問に関係する属性には興味深い意味があります。これは、将来のブラウザが標準を介して必須の<style>要素であることを意味します<body><style>要素がスコープされている限り)。

だから、それを考えると:

  • 現在、ほとんどすべての既存のブラウザがscoped属性を無視しています
  • ほとんどすべての既存のブラウザは現在<style><body>
  • 将来の実装では、(スコープ)<style>タグを許可する必要があります<body>

...その後、属性でタグを証明する限り、本文内にタグを配置することに文字通りはありません。唯一の問題は、現在のブラウザは実際にはスタイルシートの範囲制限しないということです-彼らはそれをドキュメント全体に適用します。しかし、要点は、すべての実用的な目的のために、次の条件でタグ含めることができるということです。<style>scoped<style><body>

  • scoped属性を含めることでHTMLの将来性を保証
  • 現在のところ、内のスタイルシート<body>は実際にはスコープされないことを理解してください(主流のブラウザーサポートがまだ存在しないため)


*もちろんHTMLバリデーターを怒らせるために...


最後に、HTMLにCSSを埋め込むことは不適切な慣行であるという一般的な(しかし主観的な)主張に関して、属性の要点は、scoped開発者がモジュールまたはシンジケートコンテンツとしてHTMLのチャンクをインポートできるようにする典型的な最新の開発フレームワークに対応することです。 。特定のスタイルを持つカプセル化されたモジュール式コンポーネントを開発するために、HTMLの特定のチャンクにのみ適用される埋め込みCSSがあると非常に便利です。


Mozillaのドキュメントによれば、2019年2月の時点で更新され、このscoped属性は廃止されています。Chromeはバージョン36(2014)でサポートを停止し、バージョン62(2018)でFirefoxをサポートしなくなりました。どちらの場合も、ユーザーはブラウザの設定でこの機能を明示的に有効にする必要がありました。他の主要なブラウザではこれをサポートしていません。


3
@RobertMcKee:実際にテストしましたか?私は通常、HTMLページ全体(すべてのインラインスタイルを含む)がレンダリング前に解析されることを期待します。でリンクされているcssが原因headです。 場合はこれはあなたの唯一のCSSで、そして場合ページが大きく、場合、ネットワーク接続は非常に高速ではない、そして多分あなたはunstyledコンテンツのフラッシュが表示されますが、それは最も実用的な状況で私を驚かせるだろう。
Eamon Nerbonne 2013

4
現在、Firefoxのみがスコープ付きスタイル要素をサポートしています(caniuse.com/#feat=style-scopedによる)。また、一般的なブラウザはBODY内のSTYLE要素をサポートするだけなので、必要に応じてそれを使用します。CSSをスコープに適用する必要がある場合は、CSSソースのすべてのセレクターにラッパーのID /クラスをプレフィックスとして付けることができます。私は実際には、HTMLレポートをサーバー側にロードし、AJAX経由でレンダリングするWebアプリでこれを行いました。次に、CSSの前にJavaScriptで単純な正規表現を付けることができます:cssString.replace(/(^ | \})([^ {] +)(\ {)/ g、 '$ 1' + prefix + '$ 2 $ 3')
Adamホシェク

5
のサポート@scoped、またはscoped
廃止予定

51
@KiranSubbaramanのサポート:mozilla devで(2016年7月)を読みました: scoped 属性は、ChromeとFirefoxで限定的かつ実験的に採用された後に仕様から削除されましたほぼ確実に使用されるので使用しないでくださいこれらのブラウザから間もなく削除されます。」 >> developer.mozilla.org/en-US/docs/Web/HTML/Element/...
jave.web

9
scoped属性は、現在のHTML5仕様から削除されました。
Albert Wiersch 2016

61

"スタイルインボディ"愛好家にとっての悪いニュース:W3Cは最近 WHATWGに対するHTML戦争に負けました。WHATWGは、バージョンのないHTML "Living Standard" 公式になりましたが、残念ながら、これはで許可されていませ 。短命の幸せな日々は終わりました。;)W3Cバリデーターは、現在WHATWG仕様でも機能します。(ヘッズアップの@FrankConijnに感謝!)STYLEBODY

(注:これは「現在」の場合ですが、バージョニングがないため、いつでも通知や制御なしにリンクが無効になる可能性があります。GitHubで個々のソースコミットにリンクするつもりがない限り、基本的に新しい公式のHTML標準であるAFAIK への安定した参照を長く作成します。これを正しく行うための正規の方法がある場合は、私を修正してください。)

廃止された良いニュース:

イェーイ、STYLE最終的には有効であるBODYHTML5.2のように、! (そしてscopedなくなった。)

W3C仕様から(最後の行を楽しんでください!):

4.2.6。スタイル要素

...

この要素を使用できるコンテキスト:

メタデータコンテンツが期待される場所。

head要素の子であるnoscript要素内。

体内では、フローコンテンツが期待されます。


メタサイドノート:

「ブラウザ戦争」の被害にもかかわらず、2つの途方もなく競合する「公式」HTML「標準」(の引用1 standard + 1 standard < 1 standard)に対して引き続き開発しなければならなかったという単なる事実は、「トレンチ内の常識へのフォールバック」アプローチがWeb開発が実際に適用されなくなったことはありません。

これはようやく変更される可能性がありますが、従来の知識を引用すると、Web作成者/開発者、つまりブラウザは最終的に仕様に含まれるべきもの(すべきでないもの)を最終的に決定する必要があります。現実。そして、ほとんどのブラウザでは、長い間支えてきたSTYLE中でBODY(何らかの形で、例えば参照scopedのattrを。)、その本来の性能(およびおそらく他の)罰則もかかわらず、(私たちは有料に決めるかはならない、ないスペック。)。だから、一つには、私は彼らに賭け続け、希望を放棄するつもりはありません。;)WHATWGが彼らが主張するのと同じように現実/作者に対する尊敬を持っている場合、彼らはW3Cがしたことをここでやることになるかもしれません。


3
仕様書を読みましたが、わかりません。検証するのstyleブロックのサンプルコードを提供できますbodyか?
フランクConijn

3
@FrankConijn:良い点、状況が変わり、答えが更新されました!それは本当に混乱しています。5.2と5.3の両方のW3C仕様STYLEはメタデータとフローコンテンツとして扱われますが、最新のWHATWGの「生きている」仕様は、古くて退屈な「メタデータのみ」のストーリーを伝えます(HEADでのみ許可)。そして、傷害に侮辱を加えるために、W3CバリデーターはWHATWGフレーバーに従っているようです。笑うか泣くかはまだ決めていませんが、個人的には「ブラウザ+ W3C-バリデーター」のケースで「誤解」し、BODYでSTYLEを許可することにしました。(ちなみに、忘れないでください。私たちは実際には標準の究極の情報源である必要があります。)
Sz。

テンプレートシステムで動的に背景画像のプロパティを設定したい場合は、基本的にラインスタイルで使用する以外に選択肢はありません。プログラムで生成されたスタイルブロックをhtml出力のすぐ上にドロップすることは、それほど侵襲的ではありませんでした。
GovCoder

32

ビッグサイトのコンテンツ管理システムが定期的にいくつかの<style>要素(すべてではなく一部)をそれらのクラスに依存するコンテンツの近くに配置しているのを見ると、馬は納屋から出たと結論付けます。

cnn.com、nytimes.com、huffingtonpost.com、最寄りの大都市の新聞などからのページソースを見てください。それらすべてがこれを行います。

本体のどこかに余分な<style>セクションを配置する正当な理由がある場合-たとえば、多様な独立したページ要素をリアルタイムでinclude()していて、それぞれに独自の<style>が埋め込まれている場合組織はよりクリーンで、モジュール化され、理解しやすく、保守しやすくなります。確かに、ローカル変数のように、スコープが制限された「ローカル」スタイルがあればなお良いですが、後で必要になる可能性のあるHTMLではなく、現在のHTMLで作業することになります。

もちろん、他の人が詳しく述べたように、正統性に従うべき潜在的な欠点と(常に説得力があるとは限りませんが)正当な理由があります。しかし、私にとっては、<body>での<style>の思慮深い使用がますます主流になっているように見えます。


1
実用主義FTW!
ワルヤマ2018

1
はい、あなたが正しい。例として、プラグイン内の<body>で<style>タグを使用します。それは、スタイリッシュなプラグインコンテンツへの最も簡単な方法だからです。しかし、ある瞬間、すべてのcssクラスは私のプラグインデータに対して一意です。
Avirtum 2018

7

有効なHTMLではありません。とにかく、ほとんどすべてのブラウザーは2番目のインスタンスのみを考慮しているようです。

FedoraではFFとGoogle Chromeの最新バージョンで、XPではFF、Opera、IE、Chromeでテストされています。


6

これはブラウザごとに異なると思います。ブラウザがコードを処理するにつれて、グローバル表示ルールはおそらく更新されます。

このようなグローバル表示ルールの変更は、外部のスタイルシートが遅延して読み込まれるとときどき確認できます。ここでも同様のことが発生する可能性がありますが、実際にはレンダリングされないほど短い間隔で発生します。

とにかく有効なHTMLではないので、考えても無駄だと思います。<style>タグheadはページのセクションに属します。


5

他の人が言ったように、スタイルタグはヘッドに属しているため、これは有効なhtmlではありません。

ただし、ほとんどのブラウザーは実際にはその検証を強制しません。代わりに、ドキュメントが読み込まれると、スタイルがマージされて適用されます。この場合、最後の定義が検出されたため、2番目のスタイルセットは常に最初のスタイルセットをオーバーライドします。


5

<style>タグに属している<head>すべてのコンテンツとは別に、セクション。

参照:W3C仕様W3School


52
質問は扱いません。そして、これらの厳しいガイドラインは現実にオーバーランしています。著者が自分のスタイルをhtmlヘッドに定義/含めることができない場合が多くあります。
ハビエル

3
これは2010年にも当てはまるかもしれませんが、今日の受け入れられる回答にはほど遠いものです。
Isaac Lubow

3

あなたの例では、ブラウザは何もすることを「想定」されていません。HTMLが無効です。エラー回復がトリガーされるか、またはパーサーがそれを行います。

有効なインスタンスでは、複数のスタイルシートが次々に表示されるものとして扱われ、カスケードは通常どおりに計算されます。


2

これは限られたコンテキスト、たとえばプログラマーではないユーザーが使用するWebシステム上のWYIWYGエディターなどの問題で、標準に従う可能性を制限している可能性があります。時々(TinyMCEのように)、コンテンツ/コードをtextareaタグ内に配置するライブラリであり、エディターによって大きなものとしてレンダリングされますdivタグます。また、これらのエディタの古いバージョンである場合もあります。

私はそれを仮定している:

  1. これらのプログラマーではないユーザーは、システム管理者(または教育機関のwebdev)とのオープンチャネルを持っていないため、システムのCSSルールを含めるように要求します。stylesheetsます。実際、管理者(またはwebdev)にとっては、そういう意味でのリクエストの数を考えると、実際的ではありません。
  2. このシステムはレガシーであり、まだ新しいバージョンのHTMLをサポートしていません。

場合によっては、使用styleルールがないと、設計エクスペリエンスが非常に悪くなることがあります。したがって、はい、これらのユーザーはカスタマイズが必要です。わかりましたが、このシナリオでの解決策は何でしょうか?CSSをhtmlページに挿入するさまざまな方法を考慮して、私はこれらの解決策を仮定します:


最初のオプション:sysadmに問い合わせる

システムのにいくつかのCSSルールを含めることについて、システム管理者に依頼してくださいstylesheets。これは、外部または内部のCSSソリューションになります。すでに述べたように、それは不可能かもしれません。


2番目のオプション:<link>オン<body>

使用する外部スタイルシートをbodyのすなわち、使用、タグlink、タグ内のあなたは(つまりなり、サイト上で、内部にアクセスしていた領域bodyタグやないでheadタグを)。MDNのように、これは大丈夫ですが、「良い方法ではない」との情報源もあります。

<link>要素は、のいずれかで発生することができ<head>、または<body>それは、リンクタイプ持っているかどうかに応じて、素子本体-OKを。たとえば、stylesheetリンクタイプはbody-okであるため<link rel="stylesheet">、ボディで許可されます。ただし、これは従うことをお勧めしません。<link>要素をボディコンテンツから分離してに配置する方が理にかなっています<head>

w3schoolsの<head>ように、セクションに制限する人もいます。

注:この要素はヘッドセクションにのみ含まれますが、何度でも使用できます。

テスト中

私はここ(デスクトップ環境、ブラウザー上)でテストしましたが、私にとってはうまくいきました。ファイルを作成します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タグ内)でタグを使用します。これが、Charles SalviaSzのここでの回答です。このオプションを選択するときは、彼らの懸念を考慮してください。


4、5、6番目のオプション:JSウェイ

警告これら<head>は、ページの要素の変更に関連しています。おそらく、これ教育機関のシステム管理者によって許可されないでしょう。そのため、最初に許可を求めることをお勧めします。

さて、許可が与えられていると仮定すると、戦略は <head>です。どうやって?JavaScriptメソッド。

第四オプション:新<link><head>

これは2番目のオプションの別のバージョンです。使用する外部スタイルシート<head>の使用、すなわち、タグを<link>要素あなたは(それがサイト上ではなく、内側になりますアクセスを持っているエリアbody内のタグとはいheadタグ)。このソリューションは、上記の2番目のオプションソリューションに関する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(2番目のオプションと同様に)呼び出します。

.test1 { 
    color: green;
};

すでに述べたように、これは、CSSファイルを教育機関のシステムのどこかにアップロードする方法がある場合にのみ可能に見えます。

第5回オプション:新<style><head>

タグに新しい内部スタイルシート<head>使用します。つまり、アクセスできる領域の外に新しい<style>要素を使用します(つまり、サイトでは、タグ内ではなく、タグ内にあります)。新しいオブジェクトが作成されます。bodyheadStyle

これはJSによって解決されます。1つの簡単な方法を以下に示します。

テスト中

私はここ(デスクトップ環境、ブラウザー上)でテストしましたが、私にとってはうまくいきました。ファイルを作成します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>要素(サイト内、タグ内ではなく、タグ内にある)を使用します(存在する場合)。新しいオブジェクトが作成されるか、オブジェクトが使用されます(ここで採用されたソリューションのコードで)。bodyheadStyleCSSStyleSheet

これはある意味で危険です。 まず<style> オブジェクトが存在しない可能性があるためです。このソリューションを実装する方法によっては、undefinedリターンが得られる場合があります(システムは外部スタイルシートを使用する場合があります)。 2つ目は、システムデザインの作成者の作業(作成者の問題)を編集するためです。 3つ目は、組織のITの安全性に関する方針では許可されていない可能性があるためです。だから、(他の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's 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を使用する。これにより問題が解決しますが、(コード行の)ページサイズによっては、コードの保守(作成者自身または他の割り当てられた担当者による)が非常に困難になる場合があります。

しかし、教育機関での役割のコンテキストやWebシステムのセキュリティポリシーによっては、これが独自の利用可能なソリューションになる場合があります。

テスト中

ファイルを作成します_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に次の記事をお勧めします。

  • ブラウザーのしくみ:最新のWebブラウザーの舞台裏
  • レンダーツリーの構築、レイアウト、ペイント
  • Webページを「レンダリングする」とはどういう意味ですか?
  • ブラウザのレンダリングの仕組み—舞台裏
  • レンダリング-HTML標準
  • 10レンダリング— HTML5

+1スクリプトタグを含む良いアイデアと
cscript

1

これは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>

私の推測では、ブラウザは出会う最後のスタイルを適用します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.