Reset CSSフレンズでは、内容の改善や頒布数の決定を目的にGoogle アナリティクスでアクセス情報を匿名のトラフィックデータという形で収集・解析しています。データの収集を無効化したい場合はこちらのリンクより無効にする事ができます

第3章 Reset CSSでどのような宣言がされているか

われわれはかしこいのでReset CSSでどのような宣言があるか教えるです。その前に教えてほしければ料理をよこすのです。

…満腹、満足です。解説が終わったらおかわりをよこすのです。

ブラウザがWeb上のページを読み込むときに既定で適用されるスタイルとして、ユーザーエージェントスタイルシートがあるです。ユーザーエージェントスタイルシートの内容はブラウザごとに次のURLで見られるのです。

Reset CSSはユーザーエージェントスタイルシートの宣言をリセットするためにあるです。これからReset CSSのスタイル宣言を一部ユーザーエージェントスタイルシートでの宣言も教えつつ見ていくのです。ちなみに解説するHTMLの要素は(リスト3.1)のみに絞るです。

リスト3.1: 解説するHTML要素一覧

html, body, img,
ul, ol, li,
table, tr, td,
h1, p, a, blockquote, br,
section, article, nav, aside,
input, textarea, button, select

3.1 html要素

まずはhtml要素です。ChromeとSafariではdisplay: block;の宣言だけなのです。Firefoxではdisplay: block;以外にも、unicode-bidi: isolate;という複数の表記方向が混ざる文章をどのように扱うか決める宣言もされているのです。unicode-bidiプロパティの値が表示にどう影響をあたえるかは「CSS: unicode-bidi プロパティ - Unicode文字の表記方向*1」を見るです。

[*1] http://www.osaka-kyoiku.ac.jp/~joho/html5_ref/css/unicode-bidi_css.php

sanitize.cssとressは、html要素へ対しbox-sizing: border-box;を宣言した上で、ユニバーサルセレクタへbox-sizing: inherit;を宣言しているです。これでコンテンツ領域にpaddingborderの値が入るようになるのです。これでボックスサイズの計算がより簡単になるのです。

3.2 body要素

body要素はChrome・Firefox・Safariで同じスタイル宣言なのです(リスト3.2)。

リスト3.2: body要素に対するスタイル定義

body {
  display: block;
  margin: 8px;
}

margin: 8px;の宣言は多くのWebサイトでいらない宣言なので、Reset CSSでmargin: 0;と宣言されることが多いのです。margin: 0;と宣言しているReset CSSはEric Meyer's Reset CSS、sanitize.css、YUI 3 Reset CSSがあるです。normalize.cssもv5.0.0まではbody要素に同じ宣言があったです。v6.0.0で削除されて何もなくなったのです。

3.3 セクショニング・コンテンツとh1要素

h1要素は見出しを表す要素の中でもっともランクが高い要素です。section要素やarticle要素といったセクショニング・コンテンツへh1要素を入れ子した場合は、深さに応じてスタイルが変わるのです(リスト3.3)。

リスト3.3: h1要素に対するスタイル定義

/* Chrome, Safari */
h1 {
  display: block;
  font-size: 2em;
  -webkit-margin-before: 0.67__qem;
  -webkit-margin-after: 0.67em;
  -webkit-margin-start: 0;
  -webkit-margin-end: 0;
  font-weight: bold
}
:-webkit-any(article,aside,nav,section) h1 {
  font-size: 1.5em;
  -webkit-margin-before: 0.83__qem;
  -webkit-margin-after: 0.83em;
}
:-webkit-any(article,aside,nav,section) :-webkit-any(article,aside,nav,section)
h1 {
  font-size: 1.17em;
  -webkit-margin-before: 1__qem;
  -webkit-margin-after: 1em;
}

/* Firefox */
h1 {
  display: block;
  font-size: 2em;
  font-weight: bold;
  margin-block-start: .67em;
  margin-block-end: .67em;
}

h2,
:-moz-any(article, aside, nav, section)
h1 {
  display: block;
  font-size: 1.5em;
  font-weight: bold;
  margin-block-start: .83em;
  margin-block-end: .83em;
}

h3,
:-moz-any(article, aside, nav, section)
:-moz-any(article, aside, nav, section)
h1 {
  display: block;
  font-size: 1.17em;
  font-weight: bold;
  margin-block-start: 1em;
  margin-block-end: 1em;
}

normalize.cssやsanitize.cssでは入れ子の深さによってスタイルが変わるのを無くしているです(リスト3.4)。

リスト3.4: h1要素に対するnormalize.cssやsanitize.cssのスタイル定義

/**
 * Correct the font size and margin on `h1` elements within `section` and
 * `article` contexts in Chrome, Firefox, and Safari.
 */

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

YUI 3 Reset CSSやEric Meyer's Reset CSSでは見出しらしいスタイルをすべて無くしているのです(リスト3.5)。

リスト3.5: h1要素に対するYUI 3 Reset CSSやEric Meyer's Reset CSSのスタイル定義

h1 {
  margin:0;
  padding:0;
  font-size:100%;
  font-weight:normal;
}

3.4 p要素

Firefoxでは文字のレイアウト方向や向き、文字が流れる方向を元にmarginを適用するmargin-block-startmargin-block-endを宣言しているです。CSSのプロパティはそれぞれ、文字のレイアウト方向はwriting-mode、文字の向きはtext-orientation、文字の流れる方向はdirectionに対応しているのです。ChromeやSafariではmargin-beforemargin-afterといったプロパティが宣言されて、値に1__qemが指定されているのです。互換性モードで表示するときにmarginの相殺をおこなわないためなのです。

YUI 3 Reset CSSやEric Meyer's Reset CSSなど古めのReset CSSではmarginpaddingが0になっているのです。新しいReset CSSでは特に宣言がないのです。これは新しく縦書きという概念が出てきたので、Reset CSSで文字の方向や向き、流れる方向を意識しだしたからです。結果としてユーザーエージェントスタイルシートをそのまま使ったほうがいいとなったのです。

3.5 a要素

a要素は各ブラウザのユーザーエージェントスタイルシートではスタイル宣言がないのです。normalize.cssやsanitize.css、ressではIEとSafari向けのスタイル宣言をしているです(リスト3.6)。

リスト3.6: a要素に対するReset CSSのスタイル定義

/**
 * 1. Remove the gray background on active links in IE 10.
 * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
 */

a {
  background-color: transparent; /* 1 */
  -webkit-text-decoration-skip: objects; /* 2 */
}

background-color: transparent;が宣言されているのは、IE 10でリンクをクリックしたときにグレーの背景がついてしまうのを防ぐためです。-webkit-text-decoration-skip: objects;という宣言は、英語やロシア語という言葉の一部文字をリンクの文字に指定したとき、下線が途切れてしまうのを防ぐためなのです*2

[*2] https://github.com/necolas/normalize.css/pull/573

3.6 img要素

img要素はiOSのSafariでタップしたときにハイライトを適用しないようにしているのです(リスト3.7)。

リスト3.7: img要素に対するSafariのスタイル定義

#if defined(WTF_PLATFORM_IOS) && WTF_PLATFORM_IOS
img {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
:any-link img {
  -webkit-tap-highlight-color: inherit;
}
#endif

normalize.cssやsanitize.css、ressではIE 10でリンク内に画像があるとborderが適用されるのを防ぐため、border-style: none;が宣言されているです(リスト3.8)。

リスト3.8: img要素に対する各種Reset CSSのスタイル定義

/**
 * Remove the border on images inside links in IE 10-.
 */

img {
  border-style: none;
}

3.7 ul, ol要素

ulやol要素はFirefoxやChrome、Safariで論理margin論理paddingが宣言されているです(リスト3.9)。

リスト3.9: ul要素に対するSafariのスタイル定義

ul {
  display: block;
  list-style-type: disc;
  margin-block-start: 1em;
  margin-block-end: 1em;
  padding-inline-start: 40px;
}

ulやol要素が入れ子になったとき、FirefoxとChrome、Safariで宣言しているプロパティは同じなのですが、セレクタの宣言方法が違うのです。Firefoxでは:any()という疑似クラスを使って、ulやol要素などが入れ子になったときのスタイル宣言をおこなっているです*3(リスト3.10)。:any()擬似クラスは、CSS Selectors Level 4では:matches()として仕様策定が進んでいるのです*4

[*3] https://developer.mozilla.org/ja/docs/Web/CSS/:any

[*4] https://drafts.csswg.org/selectors-4/#matches

リスト3.10: 入れ子になったul要素に対するFirefoxのスタイル定義

/* nested lists have no top/bottom margins */
:-moz-any(ul, ol, dir, menu, dl) ul,
:-moz-any(ul, ol, dir, menu, dl) ol {
  margin-block-start: 0;
  margin-block-end: 0;
}

/* 2 deep unordered lists use a circle */
:-moz-any(ol, ul, menu, dir) ul {
  list-style-type: circle;
}

/* 3 deep (or more) unordered lists use a square */
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) ul {
  list-style-type: square;
}

ただ:any():matches()の仕様が固まっていないので、ChromeやSafariでは従来どおりの子孫セレクタを使った宣言になっているです(リスト3.11)。

リスト3.11: 入れ子になったul要素に対するChromeやSafariのスタイル定義

ul ul,
ol ul {
    list-style-type: circle
}
ol ol ul,
ol ul ul,
ul ol ul,
ul ul ul {
    list-style-type: square
}

sanitize.cssでは、nav要素が親要素のときにulとol要素にlist-style: none;の宣言をしているです(リスト3.12)。nav要素内にあるulとol要素にlist-styleの値はあまり宣言しないので、このような宣言になっているです。

リスト3.12: sanitize.cssのulやol要素に対するスタイル宣言

/**
 * Remove the list style on navigation lists in all browsers (opinionated).
 */

nav ol,
nav ul {
  list-style: none;
}

3.8 table要素

Firefoxでtable要素の非推奨となった属性にスタイル宣言をしているのが面白いのです。たとえばalignframerulesが挙げられるです(リスト3.13)。

リスト3.13: Firefoxで宣言されている非推奨の属性に対してのスタイル宣言(一部)

table[align="left"] {
  float: left;
}

table[align="right"] {
  float: right;
  text-align: start;
}

table[rules] {
  border-width: thin;
  border-style: hidden;
}

他にもFirefoxだけ-moz-is-htmlという擬似クラスのようなセレクタ宣言があるです(リスト3.14)。この宣言は何が起こるのか謎なのです。かしこいわれわれでも分からないことはあるのです*5

[*5] https://jsfiddle.net/f3rp4kmu/

リスト3.14: -moz-is-htmlという謎の擬似クラスっぽいセレクタ

tr > form:-moz-is-html, tbody > form:-moz-is-html,
thead > form:-moz-is-html, tfoot > form:-moz-is-html,
table > form:-moz-is-html {
  /* Important: don't show these forms in HTML */
  display: none !important;
}

sanitize.cssではborder-collapse: collapse;の宣言があるです(リスト3.15)。これによってtableのborderがセル同士で共有されるです。セル同士をくっつけて表示したいときは便利なのです。

リスト3.15: sanitize.cssのtable要素に対する宣言

/**
 * Collapse border spacing
 */

table {
  border-collapse: collapse;
}

border-collapseの値が表示へどのように影響するのかは図3.1で示すとおりなのです。

border-collapseの宣言によって表示が変わる

図3.1: border-collapseの宣言によって表示が変わる

3.9 blockquote要素

blockquote要素はFirefoxで[type=cite]という属性へスタイル宣言があるのです(リスト3.16)。この属性はいまW3Cの仕様には無いですが、過去にはあってFirefoxではいい感じの見た目になるのです(図3.2)。

リスト3.16: blockquote要素に対してのスタイル宣言

blockquote {
  display: block;
  margin-block-start: 1em;
  margin-block-end: 1em;
  margin-inline-start: 40px;
  margin-inline-end: 40px;
}

blockquote[type=cite] {
  display: block;
  margin-block-start: 1em;
  margin-block-end: 1em;
  margin-inline-start: 0;
  margin-inline-end: 0;
  padding-inline-start: 1em;
  border-inline-start: solid;
  border-color: blue;
  border-width: thin;
}
Firefoxでblockquote[type="cite"]をプレビューしてみた様子

図3.2: Firefoxでblockquote[type="cite"]をプレビューしてみた様子

Eric Meyer's Reset CSSでは、blockquoteやq要素で引用符を消すスタイル宣言があるです(リスト3.17)。

リスト3.17: Eric Meyer's Reset CSSのblockquote要素に対するスタイル宣言

blockquote, q {
  quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none;
}

3.10 input要素

input要素はtype属性の値によって動きが大きく変わるのです(図3.3)。まるでパンサーカメレオンのようなのです。input要素関連のスタイル宣言はChromeのユーザーエージェントスタイルシートで1123行中295行、Safariは1221行中421行も充てられているのです*6。Firefoxは895行中24行がinput要素関連のスタイル宣言に充てられているです。

[*6] SafariはiOS向けのスタイル宣言もあるので行数が多いかもしれないです

input要素はtype属性の値によって挙動が大きく変わる

図3.3: input要素はtype属性の値によって挙動が大きく変わる

Reset CSSのinput要素に対する宣言はnormalize.css、sanitize.css、ressそれぞれで似ていますが微妙に違うのです。それぞれのライブラリでどのように宣言されているか解説していくです。

normalize.css

normalize.cssはブラウザ間の違いをなくす宣言だけなのです(リスト3.18)。これもv6.0.0から作者の意見を入れないようにしたnormalize.cssの特徴が示されているのです。

リスト3.18: あくまでブラウザ間の差異を埋める程度に留めるnormalize.css

/**
 * Remove the margin in Firefox and Safari.
 */

button,
input,
optgroup,
select,
textarea {
  margin: 0;
}

/**
 * Show the overflow in IE.
 * 1. Show the overflow in Edge.
 */

button,
input { /* 1 */
  overflow: visible;
}

sanitize.css

normalize.cssの宣言を元に、font-sizeline-heightの値としてinheritが宣言されているのです(リスト3.19)。親要素の宣言を受け継ぐことによって、スタイル宣言することを極力減らすようにしているです。優しいのです。

リスト3.19: normalize.cssより作者の主張が含まれているsanitize.css

/**
* Remove the margin in Firefox and Safari.
*/

button,
input,
optgroup,
select,
textarea {
  margin: 0;
}

/**
* Inherit styling in all browsers (opinionated).
*/

button,
input,
select,
textarea {
  background-color: transparent;
  color: inherit;
  font-size: inherit;
  line-height: inherit;
}

/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/

button,
input { /* 1 */
  overflow: visible;
}

input要素への宣言として他にないものはtouch-action: manipulation;なのです(リスト3.20)。ページのスクロールとズームのみを許可する宣言なのですが、IE 10だとタップ時の遅延もなくなるのです。

リスト3.20: IE 10でタップ時の遅延を無くすCSS

/*
 * Remove the tapping delay on clickable elements (opinionated).
 * 1. Remove the tapping delay in IE 10.
 */

a,
area,
button,
input,
label,
select,
summary,
textarea,
[tabindex] {
  -ms-touch-action: manipulation; /* 1 */
  touch-action: manipulation;
}

ress

ressもsanitize.css、もしくはそれ以上に作者の意見が反映されているのです(リスト3.21)。[type="button"][type="submit"][type="search"]はブラウザのユーザーエージェントスタイルシートでborder-radiusが適用されているですが、ressでは無かったことになっているです。他にもbackground-colorを透過させたりborder-styleを無くしたり大胆なのです。

リスト3.21: normalize.cssと同じく主張が強いress

input {
  border-radius: 0;
}

button,
input,
optgroup,
select,
textarea {
  font: inherit; /* Specify font inheritance of form elements */
}

/* Remove the default button styling in all browsers */
button,
input,
select,
textarea {
  background-color: transparent;
  border-style: none;
  color: inherit;
}

3.11 select要素

select要素はChromeとSafariでtext-transform: none;の宣言がされているのです。しかしEdgeとFirefoxでは宣言がないので、normalize.cssとsanitize.cssには同じ宣言があるです(リスト3.22)。

リスト3.22: normalize.cssとsanitize.cssではtext-transform: none;の宣言だけ

/**
 * Remove the inheritance of text transform in Edge, Firefox, and IE.
 * 1. Remove the inheritance of text transform in Firefox.
 */

button,
select { /* 1 */
  text-transform: none;
}

ress

normalize.cssやsanitize.cssと違って自分の道を歩いているのがressなのです。text-transform: none;も宣言していますが、他にもselect要素らしい見た目を無くすappearanceやIE独自の疑似要素へスタイルを宣言しているのです(リスト3.23)。::-ms-expandはドロップダウンの項目を見るためのボタンを表す疑似要素で、::-ms-valueはselect要素内の文字を表す疑似要素なのです*7

[*7] http://subtech.g.hatena.ne.jp/mayuki/20110923/1316786871

リスト3.23: ressはselect要素でも独自路線

/* Style select like a standard input */
select {
  -moz-appearance: none; /* Firefox 36+ */
  -webkit-appearance: none; /* Chrome 41+ */
}

select::-ms-expand {
  display: none; /* Internet Explorer 11+ */
}

select::-ms-value {
  color: currentColor; /* Internet Explorer 11+ */
}

3.12 button要素

normalize.cssやsanitize.css、ressではWebKitのバグを修正するセレクタ宣言やプロパティと値の宣言をしているです(リスト3.24)。Firefoxでもbutton要素内に画像を置いたときに生まれるborderと画像の間にある隙間が埋まるようにしてあるのです*8

[*8] http://jeffreyfrancesco.org/weblog/2011062101/

リスト3.24: normalize.cssとsanitize.css、ressの共通宣言

@mapfile(../codes/reset-css/normalize-css/button.css)
/**
 * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
 *    controls in Android 4.
 * 2. Correct the inability to style clickable types in iOS and Safari.
 */

button,
html [type="button"], /* 1 */
[type="reset"],
[type="submit"] {
  -webkit-appearance: button; /* 2 */
}

/**
 * Remove the inner border and padding in Firefox.
 */

button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
  border-style: none;
  padding: 0;
}

/**
 * Restore the focus styles unset by the previous rule.
 */

button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
  outline: 1px dotted ButtonText;
}

ress

ressはnormalize.cssやsanitize.cssと同じ宣言もあるですが、独自にcursor: pointer;overflow: visible;が宣言されているです(リスト3.25)。cursor: pointer;はユーザーエージェントスタイルシートでカーソルの宣言がないのでressで宣言しているのです。overflow: visible;はコメントにもあるように、IE8〜11はbutton要素の値としてhiddenが宣言されているのです。その宣言を無くすためにoverflow: visible;が宣言されているです。

リスト3.25: ressのbutton要素へ対する宣言

/* Apply cursor pointer to button elements */
button,
[type="button"],
[type="reset"],
[type="submit"],
[role="button"] {
  cursor: pointer;
}

button {
  overflow: visible; /* Address `overflow` set to `hidden` in IE 8/9/10/11 */
}

3.13 textarea要素

textarea要素はnormalize.cssやsanitize.css、ressで似た宣言がされているです。

normalize.css

normalize.cssの宣言は単純なのです。IE向けにtextarea要素内のスクロールバーを消すだけの宣言だけです(リスト3.26)。

リスト3.26: normalize.cssのtextarea要素へ対する宣言

/**
 * Remove the default vertical scrollbar in IE.
 */

textarea {
  overflow: auto;
}

sanitize.cssとress

sanitize.cssとressは、normalize.cssの宣言に加えてtextarea要素がリサイズできる方向を縦だけにする宣言がされているのです(リスト3.27)。

リスト3.27: sanitize.cssとressのtextarea要素へ対する宣言

/**
 * 1. Remove the default vertical scrollbar in IE.
 * 2. Change the resize direction on textareas in all browsers (opinionated).
 */

textarea {
  overflow: auto; /* 1 */
  resize: vertical; /* 2 */
}

YUI 3 Reset CSS

書かれた時期が古いので、IE 7以下で使えるCSSハックが書かれているです(リスト3.28)。*font-size:100%という書き方は@ITの「IE 6とIE 7のCSSハック16選」内にあるアスタリスクハック*9を見るのです。…見なくてもよいのです。

[*9] http://www.atmarkit.co.jp/fwcr/design/benkyo/csshack02/03.html#13

リスト3.28: YUI 3のtextarea要素へ対する宣言

input,
textarea,
select {
  font-family:inherit;
  font-size:inherit;
  font-weight:inherit;
  *font-size:100%; /*to enable resizing for IE*/
}

3.14 まとめ

Reset CSSといってもライブラリによって思想や宣言内容が違うのです。フレンズによって得意なことは違うのです。その中から自分が作ろうとしているものに適したReset CSSを選ぶのが重要なのです。カレーのスパイスが重要なのと一緒なのです。

われわれとしては、Eric Meyer's Reset CSSやnormalize.css、sanitize.cssはブラウザ既定の見た目を大幅に上書きしなければ使えるです。たとえば会社のWebサイトやキャンペーンサイトが挙げられるのです。

ressは大幅にブラウザ既定の見た目を書き換えたいときに使えるです。たとえばWebアプリやElectronで作るデスクトップアプリなどです。