水無月ばけらのえび日記

bakera.jp > 水無月ばけらのえび日記 > !importantの誘惑

!importantの誘惑

2012年2月13日(月曜日)

!importantの誘惑

公開: 2012年2月25日23時5分頃

こういう状況がありました。

特定の画面幅のときに要素を消すというのは、Media Queries (www.w3.org)を使ってdisplay: noneにすれば良いだけで、とても簡単です。

……と、思いきや、うまく行かずに難航。調べてみると、消したい要素にstyle属性でdisplay:blockが指定されており、CSSファイル内に書いたdisplay:noneがの指定が負けていたのでした。

jQueryで要素を表示したり非表示にしたりするメソッドは、要素に対してにdisplay:blockやdisplay:noneをセットすることがあります。これはstyle属性でつくので、意外なところにstyle属性がついていて、勝てない場合があるという話です。

CSSで普通にdisplay:noneを指定しても、style属性のdisplay:blockに打ち勝つことはできません。実は昔のCSS2ではstyle属性の優先度ははっきり書かれていなかったのですが、CSS2.1では明記されています。

  • count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
  • count the number of ID attributes in the selector (= b)
  • count the number of other attributes and pseudo-classes in the selector (= c)
  • count the number of element names and pseudo-elements in the selector (= d)

以上、CSS 2.1 6.4.3 Calculating a selector's specificity より

というわけでstyle属性が最強です。Selectors Level3ではどうかというと、

Note: the specificity of the styles specified in an HTML style attribute is described in CSS 2.1. [CSS21].

以上、Selectors Level 3 9. Calculating a selector's specificity より

「CSS2.1を見ろ」というスタンスで、つまりはCSS2.1と同じくstyle属性最強です。"CSS Style Attributes" にもこういう記述があります。

The declarations in a style attribute apply to the element to which the attribute belongs. In the cascade, these declarations are considered to have author origin and a specificity higher than any selector. CSS2.1 defines how style sheets and style attributes are cascaded together.

以上、CSS Style Attributes より

どう転んでもstyle属性最強です。そこで一瞬だけ脳裏をよぎったのが……「!importantを使えば勝てる」という考え。

宣言の後ろに!importantをつけると、普通のスタイル (Author normal style sheets) を上書きできるので、勝つことができるようになります (CSS Cascading and Inheritance Level 3 9. Computing weight (www.w3.org))。

しかし、!importantは禁断の技です。単独のページを作るときならともかく、汎用的なコンポーネントを設計している時に使うべきではありません。そんなことをすると、運用者がカスタマイズできなくなって困ることになるからです。!importantをつけると、それだけで複雑なルールにも勝てますが、他の人が後でこのルールに勝とうとしたとき、地雷を踏むことになります。

しかし、!importantを使ってしまえば、目前の課題はあっさり解決する上、運が良ければ問題が発覚することもない、というのも事実。

誘惑としばらく戦って、結局、このように解決することにしました。

display:noneに限って言えば、親要素に指定すれば子孫要素は全部消えます。子孫要素のstyle属性でdisplay:blockが指定されていても関係ないわけです。

どうせstyleがつくのはJavaScript有効の時だけですから、スクリプトでdivを入れて、そのdivにMedia Queriesで良い感じのスタイルが当たるように調整して完了。

今回は!importantの誘惑を何とか回避できましたが、危ないところでした。

関連する話題: Web / HTML / CSS / JavaScript

最近の日記

関わった本など

インクルーシブHTML+CSS & JavaScript 多様なユーザーニーズに応えるフロントエンドデザインパターンデザイニングWebアクセシビリティ - アクセシブルな設計やコンテンツ制作のアプローチコーディングWebアクセシビリティ - WAI-ARIAで実現するマルチデバイス環境のWebアプリケーション体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践ウェブの仕事力が上がる標準ガイドブック 5 WebプログラミングWeb Site Expert #13Dreamweaver プロフェッショナル・スタイル [CS3対応] (Style for professional)

その他サイト