擬似要素(before,after)と「content:」を使う場合の注意点

Sponsored Link



2014-06-29_135400

プログラムコードをブログなどのWebページに掲載する場合に必要な処理や見た目を整えてくれる便利なライブラリ


CSSのリスト表示を行う場合


* List-style (ul)

を使います。

この場合、リストマークというものがデフォルトで付くのですが、これがカッコ悪いです。

<ul>
    <li>ABC</li>
    <li>あいうえお</li>
    <li>タイトル
        <ul>
            <li>ABC</li>
            <li>あいうえお</li>
        </ul>
    </li>
    <li>1234567890</li>
</ul>

2014-05-07_024351

Chromeの表示例

2014-05-07_024403

IE10の表示例

ちなみに、ChromeとIEで微妙な違いがありますね。

疑似要素(before,after)を使ったリスト装飾


デフォルトのリストスタイルに付くマークがカッコ悪いので、これをCSSの疑似要素で装飾する方法があります。

たとえば、こういうやり方です。

あくまでも、「たとえば」です。

ul li:before {
    content: "•";
    display: table-cell;
    padding-right: 0.4em;
}

この方法は、非常に一般的に行われていたり、WPテーマでも行われているので、自分でやることは、ほとんどないようにも思います。

2014-05-07_024909

Chromeの表示例

2014-05-07_024921

IE10の表示例

これの利点は、ブラウザでの表示誤差がなくなるということです。
なぜなら、ブラウザ標準のリストマークには、先ほどのように見た目に違いがあるからです。

たまに、「lisy-style: none; が効かねー」という声も聞こえますが、そういう場合は大概は別のCSSにデフォルトで入っている「疑似要素を使ったリストマーク」が使われていて、そもそも「lisy-style:」や「lisy-style-type:」は元々使ってないんだよというオチが待っていたりします。

ちなみに、もう1回見てもらいたいのですが

ul li:before {
    content: "•";
    display: table-cell;
    padding-right: 0.4em;
}

「display: table-cell;」とか使ってやがったりします。
そのため、以下のようなCSSも記述します。

ul {
    font-weight: bold;
    display: table;
}
ul li {
    display: table-row;
}

というようなCSSも適用するわけですが、重要なのはテーブル化することで、「li の下にmargin作れない」という点です。

そこで、以下のように・・・・

ul li:after {
    content: "";
    display: block;
    margin-bottom: 0.25em; /*table-rowだと効かないので、上の2行でひと工夫*/
}

といったCSSを追加して、ひと工夫したりします。

あくまでも、「たとえば」のやり方です。

疑似要素(before,after)を使ったリスト装飾に画像を使うのは問題ない


この疑似要素には、画像も使えるので、この方法もよく使われます。

content: url("img/icon-red.png");

たとえば、こんな感じで指定できます。

または、画像を置くのではなく、背景画像として置くこともできます。

たとえば、こんな感じです。

content: "";
background: url("img/icon-red.png") no-repeat;

背景画像を使うパターンは、なにを期待しているかというと、画像は単に置くと、テキストの下辺が基準になるので、テキストより大きい画像だと、なんか上にハミ出てるなぁということがあるからです。

2014-05-07_031943

上図は、私が「FAQページ」で行った装飾の事例画像ですが、背景画像にはてなマークの吹き出しを置いた例です。
右のテキストが画像に対して上下中央あたりに位置していますが、これを狙ったのが、背景画像として使った理由です。

擬似要素(before,after)と「content:」を複数使う場合の注意


これらの方法で、リスト「ul」を装飾する場合、もうひとつ注意しなくてはいけないことがあります。

複数の「ul」を擬似要素(before,after)と「content:」で装飾すると、そのページのリストの装飾が無効になる

というトンデモない動作をします。

2014-05-07_043754

たとえば、上図のようにリスト装飾が2つ並ぶ場合は

以下のように書いてはいけません。

<ul class="check">
    <li>ABC</li>
    <li>あいうえお</li>
    <li>タイトル
        <ul>
            <li>ABC</li>
            <li>あいうえお</li>
        </ul>
    </li>
    <li>1234567890</li>
</ul>

<ul class="cono">
    <li>ABC</li>
    <li>あいうえお</li>
    <li>タイトル
        <ul>
            <li>ABC</li>
            <li>あいうえお</li>
        </ul>
    </li>
    <li>1234567890</li>
</ul>

2つ目以降が無効になります。

これは、HTMLの「ul」に直に装飾するCSSの場合、「ul」が連続すると、2つ目以降の装飾が無効になるからです。(下図)

2014-05-07_044524

この場合、「div」で囲うと、この問題は回避できます。

<div>
<ul class="check">
    <li>ABC</li>
    <li>あいうえお</li>
    <li>タイトル
        <ul>
            <li>ABC</li>
            <li>あいうえお</li>
        </ul>
    </li>
    <li>1234567890</li>
</ul>
</div>

<div>
<ul class="cono">
    <li>ABC</li>
    <li>あいうえお</li>
    <li>タイトル
        <ul>
            <li>ABC</li>
            <li>あいうえお</li>
        </ul>
    </li>
    <li>1234567890</li>
</ul>
</div>

「なに、それ?」

という話ですが、そうなのだから仕方ありません。将来、この動作が改善されるかもしれませんが、対策は現時点で考えておくべきでしょう。

なお、これはIEでもChromeでも起きる現象です。

「ul」に擬似要素(before,after)と「content:」で「counter()」の連番を付けるとIEでは文字色の変更ができない


擬似要素(before,after)と「content:」を使う場合、色々と気を付けないといけないことがあります。

2014-05-07_043754

さきほどの図の緑色の背景に白抜き文字の数字が付いていたパターンの装飾ですが、これは「ol」では実現できません。

なぜなら、「ol」では番号の部分に背景色や文字色を指定できないからです。

そこで、「ul」にCSSの「counter()」を使う方法で装飾を行って実現することになります。

たとえば、こんな方法です。

ul.cono:first-child > li:before {
    content: "-" counter(table-ul) "-";
    color: #FFFFFF; /*olだと文字色と背景色が指定できないのでulを連番にする(ただし、IEでは文字色も変更できない)*/
    background-color: #50B432;
    background-clip: content-box; /*table-cellだとmarginが使えない為*/
}

ただ、色々と問題もあります。

これ、IEだと文字色の変更もできない2014-05-07_050600のです。

左がIE
右がChrome

IEの方は文字色「color: #FFFFFF;」が効かないのです。(背景色はOKなくせに)

また、数字の左右に半角スペースなどの空間を入れることができず、paddingも適用できません。よって、ここでは「- (ハイフン)」を左右に入れることでごまかしています。

しかし、このように拡張性の低い方法は、結局はクライアントから「こういう風に変えて」の一言で全部作り直しになるわけです。

可能な限り使わない方が良い方法です。

時折、上記のような数字に装飾を行うCSSを使っているところもありますが、これも現状では非推奨です。

「そういう過度な装飾は、いろいろと問題があるんじゃボケッ!」と、お客さんには言えないので、「こういうことがあるから、そういう装飾はおすすめしません」と言えるようになっておくことが大事です。

IEで使う擬似要素(before,after)と「content:」でFontawesomeの相性が悪い


2014-05-07_033012

他のブログさんなどで紹介されている方法に、この擬似要素(before,after)と「content:」でFontawesomeを使うという方法が紹介されていることがあります。

たとえば、こんな感じです。

content: "f059";
font-family: 'FontAwesome';

しかし、この方法は推奨されません。

なぜなら、この方法はIEでは動作しない(アイコンが表示されない)ことがあるからです。表示されることもあるので、条件はハッキリしないのですが、同じソースなのに更新すると表示されないことがあります。これは、IE10でもそうなので、なんらかしらIEで問題があるように思えます。

IE8では完全にダメで、疑似要素で「:not()」と「:before」を組み合わせた場合にFontawesomeアイコンは表示されません。

.menu ul li a:not(:only-child):before {
    content: 'f196';
    font-family: 'FontAwesome';
}

こういった使い方でIE8ではアイコンは表示できません(「selectivizr.js」を使ってもダメ)

以下のように「:not()」や「:only-child」を使わなければ、IE8でも動作します。

.menu ul li a[href^="/index."]:before {
    content: 'f015';
    font-family: 'FontAwesome';
}

「:before」「:after」はIE8でも使えるのですが、「:not()」や「:only-child」はIE8では使えません。それを「selectivizr.js」で強引に対応させてもダメということになります。

なお、これを「ほかのJSが悪さしているっぽい」と書かれているブログさんもあるのですが、そんなことはなく、非常にプレーンなHTMLとCSSで書いてもIEでは動作しません。

よって、「ul」で擬似要素(before,after)を使って、「content:」でFontawesomeを使う方法は非推奨になります。

だが、「dl」だとIEでも問題ない

上で「「ul」で」と書きましたが、これは実は「dl」なら、擬似要素(before,after)を使って、「content:」でFontawesomeを使う方法は推奨されます。

なぜなら、IEでもきちんと動作するからです。

IEの○○○たれー、と言う話なのですが、そもそも「CSSって非常に難しい言語」だと私は思います。CSS自体は私がIT業界に入った1990年代からあるのですが、そのころから思うことは、「他の言語より難しいじゃん」ということです。

さらに、これを決めてるところが、うまく話まとまんねー連中のような気もしています。(いや、そもそも画面のデザインレンダリングを言語にするのは難しいのです)

というか、やること多すぎて、難しくなっている感じです。

それに、追加して「ブラウザ間で動作が異なる」のも、また大問題です。

ちなみに、私はCSSが使われ始めた2000年代に、「は? ホームページなんて、PDFで十分だろ!」とか言っちゃったクチで、「ネットは内容が分かればいいんじゃボケ派」なので、CSSとかHTMLとか嫌いです(笑)。

CSSでドはまりなんて、よくある話です。
ブラウザできちんと検証(IEとChromeだけでいいですが)しておきたいものですね。

Sponsored Link

最新記事はトップページで!

京都発・地方が盛り上がるグルメや観光に撮影ロケ地の話題を提供!


購読するならRSSをご利用ください!

RSSはこちらをご利用ください。


マスコミ各社様の記事使用規約についてはこちらをご覧ください。

当ブログでは掲示板やSNSなど他メディアでURLや記事を紹介することはございませんので、掲示板などで記事を紹介されていても一切無関係です。誤解なきようお願いいたします。
当ブログで転載しているTweetはTwitter社の規約(2013/10)に準じた形式(API利用)によって許可された範囲で行われています。また、Tweet内容の所有権はTwitter社の規約によりTweet元のアカウント所有者にあります。そのため、当ブログでその所有権を主張するものではありません。Tweet内容については責任は負いませんので予めご了承ください。