body内のstyle要素が一定条件下で再びエラーに

body内のstyle要素が一定条件下で再びエラーに

webのあれこれ
2018/11/21 10
vanillaice (Akira)
vanillaice (Akira)
Instruction HTML CSS VanillaJS 中級者向け トラブル対処 Validation

head内限定だったstyle要素の記載がHTML5.2からはbody内にも書けるようになりました ということで私のその件を記事にしております。 ところがW3C validatorでbody内style要素が再びエラー対象に。その理由と解決策など。

html5.2ではstyle要素をbody内に書けるようになりました

意味わからへーん!な方とそうでない方といらっしゃると思いますけれども、結構重要だと思いますので記しておきます。 html5.2が既に正式勧告を済ませてますが、追加要素や廃止要素などに加え style要素をbody内に書くことがinvalidではなくなりました * invalid (インヴァリッド) = 無効, 正しくない の意...

CSSの記載の仕方は複数あります

FC2ブログの特徴などを絡め、style要素の扱いの歴史をざっと説明します。 まず style要素 が何なのか。

【html + スタイルシート(エクスターナルCSS)】

<!-- これはhtmlです 記事内に記します -->
<div class="xxx"> あいうえお </div>
/* これはCSSです スタイルシートに記します */
.xxx {
  font-size: 16px;
}

htmlはhtmlファイルに、CSSはカスケーディングスタイルシートに分けて記す方法で、これが主流であり最も推奨される形です。
FC2で言うと「テンプレート編集」ページの上段にあるのがhtml、下段にあるのがスタイルシートです。
この方式を取る場合には 記事内でCSSを扱うことがはありません。みなさんが記事を書く際に記すのはhtmlの方だけです。

【htmlのstyle属性を利用(インラインCSS)】

<!-- これはhtmlです 記事内に記します -->
<div style="font-size: 16px;"> あいうえお </div>

html要素にstyle属性を付与してそこへ直接CSSを書き込む、というのがインラインCSSです。
記事を書く際にFC2ブログエディターのツールバーを利用することがあるかと思います。ツールバーはこの方式を利用しています。

【html + style要素を利用(インターナルCSS)】

<!-- これはhtmlです 記事内に記します -->
<div class="xxx">
  あいうえお
</div>

<!-- これはhtmlです 記事内またはテンプレートhtmlに記します -->
<style>
.xxx {
  font-size: 16px
}
</style>

style属性ではなくstyle要素です。こちらも通常は「インラインCSS」と呼ばれますが、今回はstyle属性と区別したいので「インターナル」という呼称を使います。今回の記事はこのstyle要素が主役です。

htmlと分けてあるCSS内容は通常はスタイルシートに記載するのですが、使用頻度が非常に低い場合はスタイルシートに記すと無駄が生じますので、一時的な利用にならこのstyle要素が最も都合が良いんですよね。
記事を書く際にはhtmlと共にstyle要素も同時に記すことになります。つまり「本文」「追記」のいずれかに書くことになります。

で、style要素をFC2ブログで使用する機会を考えますと、概ね以下の2ケースではないかと思います。

  • FC2ブログプラグイン(公式プラグイン)
  • 使用頻度の低い限定的使用を個別記事で行う

公式プラグインの一部には実際にstyle要素が使われています。これはかなり昔からだと思います。
実はこの方式はこれまでずっと やってはいけない方法 ではあったんですね。htmlの構文ルールとして許可されていませんでした。
とはいえ公式プラグインも「style設定」というのは必要ですし、各ユーザーのCSSとプラグインのそれは切り離されていますのでどこかにCSSを書かなければ仕方がないわけで。
なのでこれは「致し方なし」という判断でこうなっているのだと思います。つか、style属性使えば良くね?とは思うが ←

「やってはいけない」について、htmlのこれまでのバージョンではルールとして style要素はhead内にしか書いてはいけない と決められていました。
公式プラグインのhtmlソース内にstyle要素が有る場合には head内 ではなく body内 に存在することになり、それはルール違反だよ、と。

【これはOK】

<!DOCTYPE html>
<html lang="ja">
  <head>
    ...
    ...
    ...
    <style>.xxx {font-size: 16px}</style>
  </head>
  <body>
    <div>
      ...
      ...
      ...
      <div>
        プラグイン内容
      </div>
    </div>
  </body>
</html>

【これはダメ】

<!DOCTYPE html>
<html lang="ja">
  <head>
    ...
    ...
    ...
  </head>
  <body>
    <div>
      ...
      ...
      ...
      <div class="plugin">
        プラグイン内容
        <style>.xxx {font-size: 16px}</style>
      </div>
    </div>
  </body>
</html>

こういうルールだったんですね。みなさんが「最新記事(サムネイル画像つき)」プラグインをお持ちであればhtmlソースを開いてみてください。ソースの書き出しに <style type="text/css"> の文字列を見つけられると思います。そしてそれが【これはダメ】の形に該当していた(いる)、ということです。

style要素の扱いの流れ

これまでの流れを大まかに説明しますと

head内にのみ記載を許可 --- html5.1まで

body内への記載も許可 --- html5.2以降

とまぁこういうことなんですが、body内っつっても具体的にどこ??? 問題(笑)

【これはOK】

<!DOCTYPE html>
<html lang="ja">
  <head>
    ...
    ...
    ...
  </head>
  <body>
    <style>.xxx {font-size: 16px}</style>
    <div>
      ...
      ...
      ...
    </div>
  </body>
</html>

これはOKです。body要素の直下の子要素というか、直系である場合。じゃあ以下のような場合は?

【これは?】

<!DOCTYPE html>
<html lang="ja">
  <head>
    ...
    ...
    ...
  </head>
  <body>
    <div>
      ...
      ...
      ...
      <style>.xxx {font-size: 16px}</style>
    </div>
  </body>
</html>

body要素の子ではなくdivが噛んでますので、これは子ではなく孫です。このパターンが許可されるのか?という点ですが…

html5.2勧告後、W3C validatorはこの孫パターンの形をエラーとしない判定結果を出していました。ところが最近になって5.2勧告以前と同じエラー表示を行うようになっています。
変更なの?変更されたの?それとも元々ダメで何かの手違いだったの?(笑)
逆にdivやらsectionやらの子要素でもエラーにならないから驚いたんだけども。逆に(笑)
やっぱダメやったんかー ( ̄∀ ̄;)

喜びもつかのま

「style属性がbody内で使えるよ、スタイルシートに書かなくても 記事に直接書けるから便利になったよ。ヒャッホウ」 とか言ってましたが、それがやはり「ダメ」ということになると逆戻りですねぇ (´・ω・`)
だってみなさんが「一時的CSS」をどこに書くかといったらもう「記事内」でしかありえないわけなんですよ(スピード対策を除く)
そしてその「記事内」は必ず何らかのhtml要素としてマークアップされています。
div要素かもしれませんし、sectionやarticleかもしれませんが、ともかく記事内でstyle要素を利用すればbodyの孫あるいはそれ以降の子孫確定です。

これ一般的なサイトでは特に問題ないというか。ホントはフツーに考えても当たり前というか。実は(笑)
入れ子できる要素は「フローコンテンツだけですよ」「フレージングコンテンツだけだよ」とかあるわけですもんね。
style要素はscoped属性をつければフローコンテンツですがそれでもやはりエラー判定となるもよう(どのみちscopedは草案で破棄されました)

ただここは FC2ブログ なわけでして、FC2ブロガーさんがstyle要素を一時的装飾として利用する場合はbodyの「長男」「次男」「三男」〜にすることができませんよね。記事内に記せば必ず「長男の子」「初孫」「ひ孫」とかそういう関係になります。

でもやっぱり使いたいじゃないですか (´・ω・`) ←
だってホントに1年のうち1・2度しか使わないCSSとかもあるんですよね。
例えばこういうのとか ↓

YouTubeを飾ってみる

今回は完全に遊びです。 YouTubeなどの動画を着飾ってみる。たまにはそういうのも良いかな。と (´・ω・`)...

これをスタイルシートに記すと、ほとんど使われることがないのに結構な文字数取りますからスタイルシートのデータサイズは大きくなります。 あと、スタイルシートはテンプレートを変更したときに移植作業が発生します。style要素を記事内に書いておけばその心配はありません。テンプレート変更で「デザインぐちゃぐちゃになった! (;ωq`)」という悲しい出来事を避けられます。

解決策「JSでhead内にstyle要素を差し込む」

もうこれしかないわな (´・ω・`)
外部スタイルシートにするとまたさらに管理が煩わしいですし、通信リクエストも増えてしまいますのでやはりここは直書きで。

<script>
var styleElm = document.createElement('style');
styleElm.type = 'text/css';
styleElm.innerText = 'ここにCSS内容';
document.getElementsByTagName('head').item(0).appendChild(styleElm);
</script>

(一応 let, constではなくvar にしておきます)
html5テンプレートの場合は3行目の
styleElm.type = 'text/css';
を省略しても構いません。

これもう定形ですから使用する際には「ここにCSS内容」の部位以外を変更することはまずありません。
これまでのサンプルを使うと

<script>
var styleElm = document.createElement('style');
styleElm.type = 'text/css';
styleElm.innerText = '.xxx {font-size:16px}';
document.getElementsByTagName('head').item(0).appendChild(styleElm);
</script>

こうですね。指定が複数ある場合には

<script>
var styleElm = document.createElement('style');
styleElm.type = 'text/css';
styleElm.innerText = '.xxx {font-size: 16px; color: red} .yyy {text-align: center}';
document.getElementsByTagName('head').item(0).appendChild(styleElm);
</script>

こうして横に続けて書き、CSSソース間での改行はおこなわないようにします。こうするとバリデートエラーを避けられますね。

重要!注意点

JSコードは必ず 「追記」に記載します。
「本文」に書いてしまうとコードの文字列がOGPのdescriptionに含まれてしまい、当然ブログカードにも抽出されてしまいます。なので必ず「追記」の方へ。対象htmlが「本文」にあるとしてもJSは「追記」へ記載。
というか記事内でJSを使うときは原則として常に「追記」の方へ。

もう一点。CSS内に シングルクォーテーション が含まれる場合にはダブルに変更してください。font-family指定などでシングルが使われているかもしれませんので注意。

まとめ

そこまでする必要あるんかい?と問われれば、あるっちゃーある。無いっちゃーない (´・ェ・`)
一般ブロガーさんならばそんなにテクニカルなことをする機会も少ないような気がしますが、記事内で「なんらかの装飾を楽しんでいる」という方も散見されます。そしてその多くは「初心者の方」だったりするんですよね。
構文エラーというのは無い方が良いに決まってますし、思わぬレイアウト崩れを引き起こす可能性もありますので修正できるものならば即座に行動、ということで。

というわけでYouTubeの記事も対策を追記しておきますので、ご利用の方はご確認ください(というかこの記事へ誘導するだけの手抜きですが)
まぁ、絶対直さないとだめ!という案件ではありませんが、いややっぱダメかな?どーお?(聞いちゃってるよ)
余力の有る方はどうぞ ^^;
早めに切り替えておけば後々自分が楽、ということで。

* しょっちゅう使う、という方はスタイルシートに書いたら良いんやで?それが一番の推奨です。

----- 追記 2019.4.7

追記しようと思いながらずっと忘れて遅くなってしまいました。ごめんなさい。

コメント欄で有志の方からinnerTextではなくinnerHTMLで書くのはどうでしょうというご提案を頂きました。S様ありがとうございます(内緒コメントなので伏せ字にしておきますね)

innerHTMLで書く場合には ソース内改行OK になりますので、初心者の方はこちらを用いる方が良いかもしれません。ただし 用いる記号が違います ので注意が必要です。この記号がキーボードでとても出し難いですから、ひな形をしっかり保存して記号を消したり変更したりしないように留意してください。

<script>
var styleElm = document.createElement('style');
styleElm.innerHTML = `ここにCSS内容`;
document.getElementsByTagName('head').item(0).appendChild(styleElm);
</script>

innerTextを用いる場合 ここにCSS内容 を挟む記号はアキュートアクセント ' です。
innerHTMLを用いる場合にはグレイブアクセント ` です。

winでこの記号どうやって出すんですかね (´・ω・`)
とりあえずmacの場合は
option + shift + _ です。

innerHTMLの場合は例えば

.xxx {
  color: black;
}
.yyy {
  background: white;
}
上記内容を ここにCSS内容 の文字列と置換してOKです。なのでメンテナンスや変更作業はしやすいですね。ただしくれぐれも記号には注意。

 10

There are no comments yet.
hige
ひえっ

記事内のスタイルシートはダメなんですか。
いくつかやっちゃってます。
どの記事に書いたのやら。

2018/11/22 (Thu) 22:05
vanillaice (Akira)
Akira
To higeさん

higeさん、こんばんは (o'ω')ノ

もしかして私がこのような記事を書いたせいでしょうか。
ごめんなさい… ( ̄∀ ̄;)
私もいくつか書いているはずで、覚えているページはJSに変更しましたが残りは調べきらん (´・ェ・`)
目に見えて表示が崩れるといったことはありませんし、Googleのクローラーも無視しているようですがやはり内部的には良くないですよね。
ごめんなさいね。ホント。もっとよく調べて詳細に記せば良かったと反省しています (*_ _)

2018/11/22 (Thu) 22:42
hige
No title

 いえいえ、とんでもありません。
 これは私の勝手な判断でやったことです。
 何しろ独学で、系統立てた教則本を読んだことも、教育を受けた訳でも無いので基本的な部分に無知なためです。
 記事内に<style>・・・・</style>でCSSを書いてもちゃんと適応されてるので、(Firefox、Chromeで確認)使っていいのだと勝手に思ってました。
 1記事だけは確実にやってしまってるので、JSを試してみたいのですが、CSSがかなりの量なのでまだ試せてません。
 改行が沢山入ってるのと、段落の半角スペースも一杯あるのでこれを削除するのが大変かも。
 エディタの検索/置換が使えれば楽ちんなんですが。
 短いCSSもどこかの記事で使ってるのですが、これはちょっと思い出せないです。

 重要な情報をありがとうございました。

2018/11/23 (Fri) 08:47
vanillaice (Akira)
Akira
To higeさん

こんにちは (●'0'●)/

CSSはこちらで圧縮してくださいね ↓
https://www.minifier.org/

一瞬で終わります。
私も「見つかったら」修正しようと思います ^^;

2018/11/23 (Fri) 13:42
hige
旨くいきました

かなり項目の多いCSSを記事内に書いていたので、精神的に余力ができた今日、やってみました。
https://blgid1974.blog.fc2.com/blog-entry-508.html

すごい。script を装飾される本文の後(追記)に書いても適用されている。
最初、旨くいかなくて ??
script の styleElm.innerText の内容(CSS部分)が ' (シングルクオーテーション)で囲まれてるのですが、この中にfont-style の部分があって、フォント名もシングルクオーテーションで括ってまして・・・・
この部分を " (ダブルクオーテーション)にして解決。この注意事項をすっかり忘れてました。

一つ質問です。
styleElm.type = 'text/css';
これを削除してもちゃんと表示されます。
なくてもいいんでしょうか。

2018/12/07 (Fri) 20:42
vanillaice (Akira)
Akira
To higeさん

こんばんは ('0')/

そうですね。注意点として書いて於けば良かったですね。
html, CSSの推奨はダブルクォーテーションなので、JSはシングル、html, CSSはダブル、と私は方針を決めていますがみんながみんなそういうわけではないですよね。
それに私もフォントはシングルで書いてます(笑)
これhigeさんが日々お勉強されているから気づけましたよね。普段html使わない方だとたぶん気づけません。

type属性はhtml5の場合には省略してOKです。寧ろ省略をおすすめします。
html4の場合は必要です。

2018/12/07 (Fri) 20:58
hige
type属性

省略で良かったんですね。
解る範囲でHTML5で書いてます。
実は外部バナーとか外部タグとかもHTML5で書き換えてしまいました。今のところ大丈夫みたいです。
じぃじぃもお勉強中です。でも年寄りは学習効果がなかなか刷り込まれない。

私は、この記事だけと云うスタンドアローンで処理したいものがあるので、たまに記事ごとで装飾をしています。

今回の記事もありがたい。

2018/12/07 (Fri) 22:12
vanillaice (Akira)
Akira
To higeさん

私も日々勉強です ^^;
web事情は刻一刻と変わりますね。頭の体操にはなっているはず(笑)

2018/12/08 (Sat) 00:22
-
管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます

2019/02/27 (Wed) 02:18
vanillaice (Akira)
Akira
To style要素の件 内緒さん

こんばんは。

初心者の方やdataURIを利用する時なんかはその方が良いかもしれませんね。情報ありがとうございます。勉強になります :)

2019/02/27 (Wed) 02:42

テンプレートに関するご質問・不具合のご報告の際はご自身のブログアドレス記載必須です。
ご質問の前に 必ずお読みください
テンプレートに関するご質問時のお願い

必ず該当テンプレートの専用記事にお願いします。無関係な記事・別のテンプレート専用記事でのコメントはお控えください。
テンプレートカテゴリ
テンプレート一覧

webのあれこれ