Simplicityを少し改造してみた 番外編 part20 cssのfloatの弊害をブログカードで説明する

Simplicityのブログカードにて、問題がひとつあるのに気づかれた方がいるでしょうか?

ブログカード自体の表示に問題はなく、デフォルトの状態で利用する分には不具合は起きません。と言っても、不具合が起きたとして何かしらブログ全体に問題が出るというものではないので安心して下さい。

その問題点というのが、cssのfloatにおける「高さが無くなる」と言う点なのです。
古のcssでは、何かしらの子要素を横に並べるという場合に、inline-blockであったり、floatが使われたものでした。今でももちろん使われますし、使ったからと言って必ずしも問題が出るというわけではありませんが、floatに関しては「高さが無くなる」と言う点でレイアウトが崩れるという弊害が生まれる場合が多々あります。

何故、高さが無くなるのか。それは文字通り、floatというのは浮いているのです。

考え方としては、ある文章と画像があって、文章を画像に回りこませたいと言う場合にfloatは使われます。

本来、

何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章

このようにして、画像と文章がある場合に、

何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章

このようにして、赤背景の四角にfloat: left;を入れるだけで文章が回り込みます。

何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章

もちろんfloat: right;として右も可能です。文章の上下にスペースがあるのはPのデフォルトのスタイルで1emずつスペースが開くようになっているからです。
例えば、

何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章

このようにして、背景赤のブロックをPの中に入れるとまぁ問題ではなくなります。

さて、この赤背景のブロック。これはheightが入れてあります。width,height共に100pxとしているので、この要素自体には高さがあります。高さがあるものを浮かせているだけなので、これは大きく問題はでません。

では、次のような場合はどうでしょうか?

何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章 何かしらの文章

文字が入っていたりする場合はどうなるか
文字が入っていたりする場合はどうなるか
ほらだんだん表示がおかしくなってきましたね。

htmlがどういう状態かは以下の通りです。

これまでは、pがありそれ自体が高さを持っていました。また、赤背景のブロックにもheightを入れていたりして一見上手く右左と並べられているようですが、下の色付き背景に文字を入れたものなどは、それを囲むボーダーのブロックが潰れてしまっています。これがいわゆる高さが無くなるという問題点です。

これはSimplicityの#main、#sidebarとそれを囲む#body-inも同じことが言えます。

ちょっと端折っていますが、Simplicityのメインの記事とサイドバーはこのようになっています。

#mainにはfloat: left;が入っていて、#sidebarにはfloat-rightが入っています。なので、#body-inは高さを持っていないと言うことになるわけです。高さがなくなると、clear: both;などを入れない限りつめ込まれていきます。つまり、#footerがそのまま書いてあるとした場合は、

#main
#sidebar
#footer
こんな感じになってしまうわけです

simplicityの場合、clear:bothが入っているので、一応回り込みの解除はできていますから、見た目には問題はありません。またこれら問題点を解決するための方法としてclearfixが入っているので特別問題は無いのです。が、ブログカードはどうかというと、以下のサンプルを見てもらうとわかります。

See the Pen blog-cardで見るfloatの弊害テスト(スマホサイズまでリサイズしてみて下さい) by Hidekichi (@Hidekichi) on CodePen.

一番上がオリジナルで、2つ目、3つ目はそれらを何とかするための解決案です。
オリジナルのフッタ部分、つまりサイトアイコンとアドレスやらの部分が枠を突き抜けてますよね?
これがいわゆるfloatのわかりにくい問題点のひとつで、原因は高さが無くなることによる為のものです。しかしこれは、通常の場合には起こりません。ブログカードの幅が想定より狭くなった時に、起こりうることなのです。なので気づいていない方もまだたくさんおられるのではなかろうかと思います。

どういう場合に起こりうるかというと、サイドバーにブログカードを入れた時に、サイドバーが300px以下の状態になった場合です。例えばサイドバーにpaddingが仕込まれているとかです。他にもスマホで320pxの表示幅しか無い所に左右にpaddingなりmarginがあって表示サイズが300px以下になった場合などです。
ブログカードにはmin-width: 300pxが入ってますが、幅が300pxの時に、ブログカードの抜粋が高さ(min-height:155px)を超えるとはみ出すわけです。

これの解決方法の一つは、高さがないのであれば高さをもたせれば良いと言うだけのことです。
floatは浮いていて高さがありませんから、.blog-cardの枠を押し広げることができません。ここがポイントです。もし何かしらfloatが入っている親要素に高さがあれば.blog-cardは押し広げられるわけです。

そんな時の魔法のスタイルが、

です。cssで書くと何度もセレクタを入れなくてはいけないので面倒臭そうな感じですが、scssだと、

こういう感じでしょうか。つまり、擬似要素をtableで入れて、その後にclear: both;を入れることで確実にその間にあるものはtableで挟まれ、その親となる要素に高さができるというわけです。実際には、

こういう感じになるかと思います。

2016/10/30 追記

これだけでもfloatしている要素に高さをもたせることができます。

これはとても便利な方法ですが、現在の所、Simplicityの#body-inに適用してはいけません。スクロール追従のスクリプトでサイドバーに高さを持たせることになるとまた違う不具合がでてしまう場合があるからです。よって、もう少し狭い範囲で、このようにブログカード等で利用するのが良いかと思います。

サンプルの一番下にあるflexのバージョンでは、オリジナルの通りの見た目にするためにしていますのでこういった感じになってますが、オリジナルを構成しているhtmlが

こういう構造なので何度もflexの定義をしたり色々と手を加えていますが、footer部分はもう少し手を抜いて書けます。

.blog-card-footerの中には、3つの子要素があり、サイトの情報とはてブの情報、そして日付と横並びになっています。html的には、

こうなっています。これらは、横並びになっているだけですから

これだけ入れるだけで横並びになって、縦は自動的にセンターに揃います。後はそれぞれの間隔をどれぐらい開けるかですが、
.blog-card-siteと.blog-card-hatebuの間は5pxとした場合、

だけでよいですし、.blog-card-dateを右寄せにしたい場合は、

こうするだけで勝手に右寄せになります。つまり、はてブと日付の間は特に考慮しなくても良いわけです。.blog-card自体はmin-widthが設定されているので、それ以下にはなりませんからはてブが非表示であれば最小幅になった場合でも左寄せと右寄せの関係は変わりません。よってfloatは不要になります。
もし仮に、はてブが表示されてそれが最小幅になった時に日付がはみ出すと言う場合は、勝手にflexが折り返しをして幅100%で表示するので、特別問題はないでしょう。
もしその際に、日付が右寄せになるのがマズイのであれば、はてブにmargin-right: autoを入れればよいのではなかろうかと思ったり。

これらfloatはSimplicityで結構な場所で使われているので、もし高さ不足によりはみ出しなどがある場合は、その親要素に擬似要素にて見えないテーブルのブロックを入れ、clear: bothを入れることで親要素に高さができると言うのを覚えておくとスタイルが崩れることを防ぐことができます。

2016/10/30 別の例

See the Pen blogcardをflexで書き直す by Hidekichi (@Hidekichi) on CodePen.

全体的にflexで書き直しました。
flexを利用することで、不要になるプロパティは//ctというのが入っています。このサンプルでは、スニペット(.blog-card-snippet 抜粋)部分に高さ制限がしてあるデフォルトのblog-cardから、どんな高さになっても問題がないように修正してあり、かつ高さ制限のため非表示になっていた抜粋全文が表示されます。
実際にcodepenのエディット画面で、resiltの表示領域を触ってもらえればすぐにわかると思いますが、サムネイルとタイトルの間のスペースやフッター部分と抜粋部分の間のスペース部分が拡大縮小問わず正しく動作しているのが見てもらえると思います。

他の例 新着記事ウィジェット

追記 2016/06/01 16:22

Screenshot_from_2016-06-01 16_19_35先ほど、フォーラムに返答していて気づいたけれども、新着記事でもやはりfloatによる弊害があるのに気がついた。このサムネイルを見て頂けるとわかるように、ulを選択している中、下のスペース(黄色部分)にはみ出しがあるのに気がついてもらえるだろう。

liがulを押し広げているが、サムネイルがfloatしているためにliの部分までしか高さがないということだ。デフォルトのように、背景が透明(あるいは白)で、こういった要素のはみ出しのような現象が起きた場合は特別対処する必要はない。デベロッパーツールなどで見ない限りは、このようなはみ出しにすら気が付かないからだ。

しかし、例えば新着記事を何かしら背景で囲んだりした場合に、paddingを入れたとする。左右が枠にくっついているので、

こういう状態にしたとする。このpaddingは、高さのあるliで押し広げられたulの外にかかるので、ulにマージンがない場合は、背景をつけた下スペースがなくなってしまう。もしpaddingを0 5pxではなく、padding:5pxとした場合でもやはりボトムのスペースがないだろう。

こういう時は、ブログカードと同じように

こうすれば高さを得ることができる。

スポンサーリンク

シェアする

フォローする