段組みのCSS。
カラムを使って2段組みレイアウト
ここまで、“floatプロパティ”と、“displayプロパティを使った3つのレイアウトモード(table
、inline-block
、flex
)”を使って、2段組みレイアウトをしてきました。次は、冒頭でも書いてた、文章を読みやすくする目的のレイアウトを組むために用意された、“段組”のためのプロパティで、2段組みレイアウトしてみたいと思います!
段組のためのCSS
CSSで、文章を読みやすくするレイアウトを作るために、columnsプロパティが用意されています。これを使えば、Webでもエディトリアルデザインでいうところの“段組”を作ることができます。
例えばcolumnsプロパティに任意の整数を指定すれば、その要素の内容を指定した数に分割して、段組でレイアウトされます。
ここでは“2段組”で、段の間隔(column-gap
)を2文字分空けて、段の間に1pxの仕切り線を入れてみました。仕切り線は、段の隙間のちょうど真ん中を通るように引かれます。
p {
columns: 2;
column-rule: 1px solid #cdcdcd;
column-gap: 2em;
}
上の例では画面幅を狭めてもずっと2段組でレイアウトされ続けるのですけれど、単位付きの値を指定すれば、その要素の内容をその幅が入り切るように分割するようになります。試しにここでは、ひとつの段の幅を12文字分(12em
)となるように指定してみました。画面幅に合わせて、1段あたり12文字を目安に、段数がいい具合に切り替わるようになってると思います。
p {
columns: 12em;
column-rule: 1px dotted #cdcdcd;
column-gap: 3em;
}
columnsプロパティには、段数と段の幅を同時に指定することもできて、下記のように、2つの値を半角スペースで区切って指定します。ここでは、段数は2段に制限しつつ、段の幅が12文字未満になると1段に切り替わるようになってるはずです。完全に成り行きですけれど、「これぞWeb」って感じがしますよねー:D。
p {
columns: 2 12em;
column-rule: 1px dashed #cdcdcd;
column-gap: 4em;
}
ただし、columnsプロパティは、上で見てきたように、段を等分することしかできないので、ページ全体のレイアウトには不向き。なのですが、ここではちょっと無理して、ページレイアウトに使ってゆきたいと思います:D。
※この記事では、columnsプロパティを使ってページレイアウトすることを、“カラムレイアウト”と表記することにします。
ヘッダーとナビゲーション
まずは、ヘッダー部分です!
おもむろに、nav要素に対してcolumns: 2
を指定、ナビゲーションにはcolumns: 5
を指定します。※メディアクエリなどはフロートの時の指定をそのままです。
@media print, (min-width: 415px) {
.nav-list {
columns: 5;
}
.nav-list li {
border-left: 1px solid #eee;
}
}
@media print, (min-width: 768px) {
header nav {
columns: 2;
line-height: 80px;
}
.nav-list a {
padding: 0 2em;
}
}
なんだかいい感じにレイアウトされたかもしれないですね(無理してる割に)。ナビゲーションボタンの間に妙な隙間ができてるのと、テキストが中央に揃っていないのが惜しいです…!妙な隙間はcolumn-gapプロパティのデフォルトの値が関係しているのかな、と思うので、column-gap: 0
にしてみます。あとは、a要素の左右のパディングを無くして、テキストを中央揃えにしたら、いい感じになりました。
@media print, (min-width: 415px) {
.nav-list {
columns: 5;
column-gap: 0;
}
.nav-list li {
border-left: 1px solid #eee;
text-align: center;
}
}
767px以下の時にボタンが小さくなりすぎるのは、どうやらナビゲーションボタンの横幅に20%
を指定しているのが原因のようです。li要素の中で20%の横幅になっちゃうみたいですね。横幅の指定を削除したら、整いました!
メインコンテンツとサイドメニュー
ここも一旦おもむろに、#contents
に対してcolumns: 2
を指定します。なんと、コンテンツエリアの内容が全部そのまま2段組に流し込まれてるんですね、おもしろい。けど、メインビジュアルだけは横いっぱいに広げたいところ。テーブルレイアウトでいう“テーブルキャプション”みたいなことができたらいいんだけれど…。
@media print, (min-width: 768px) {
#contents {
columns: 2;
}
}
column-spanプロパティを使えば、カラムレイアウトにおいて、特定の要素を、列をまたぐように配置することができます。ここでは、all
という値※を指定して、すべての列をまたぐように配置します。※値にはall
とnone
しか用意されてません。。
メインコンテンツとサイドメニューの間隔は、column-gapプロパティで指定します。
コンテンツエリアが等幅ではありますが、なんとなくレイアウトできていることとして、次へ進みたいと思います…!
@media print, (min-width: 768px) {
#contents {
columns: 2;
column-gap: 40px;
}
.visual {
column-span: all;
}
}
メインコンテンツの内容がサイドメニュー側に流れ込んでしまってますが、お知らせ一覧はメインコンテンツの側に配置しておきたいところ…!
そんな時にはbreak-insideプロパティで調整します。これはカラムレイアウトした時の、改列(?)を制限するためのプロパティ。ここでは、main要素と、aside要素に対して、avoid
(避ける)という値を指定します。これで、メインコンテンツとサイドメニューでは、その要素の最中で改列されることがなくなるはずです。
うん、ちゃんとお知らせ一覧がメインコンテンツの一番下に配置されるようになりましたね!
@media print, (min-width: 768px) {
⋮
main {
break-inside: avoid;
}
}
しかし、ここまでChromeでしか確認してませんでしたが、Firefoxで見てみると、メインビジュアルが横いっぱいに広がってないし、メインコンテンツとサイドメニューもごっちゃになったままだし…、最初のレイアウトから何も解決できてないじゃないですか…XO!Firefoxは、column-spanプロパティもbreak-insideプロパティもサポートしていないのですね…(2018年9月現在)。
どうしてもcolumnsプロパティじゃなきゃいやだ、という場合には、マークアップで調整するしかないです…。
なので、ここでは、列をまたぐレイアウトは諦めて、メインビジュアル含めて2段組みのレイアウトで進めてゆこうと思います。ということで、column-spanプロパティとbreak-insideプロパティの指定はなくします。
こざっぱりしちゃいましたね。
@media print, (min-width: 768px) {
#contents {
columns: 2;
column-gap: 40px;
}
}
とはいえ、文章中に画像があるところが、途中からメインコンテンツ側とサイドメニュー側をまたいでしまっているのは、なんとも読みにくいので避けたいですね…。
Firefoxでは、break-insideプロパティはサポートされてないけれど、似たプロパティのpage-break-insideプロパティはサポートされてるので、このプロパティで代用してみようと思います。
page-break-insideプロパティは主に印刷時の改ページを制限するためのプロパティ。ここでは、section要素に対して、さっきと同じくavoid
という値を指定します。
@media print, (min-width: 768px) {
⋮
section {
page-break-inside: avoid;
}
}
コンテンツエリアのレイアウトが落ち着いたので、それぞれのセクションを段組みしてゆきます!
バナー一覧と商品一覧と記事一覧
ひとまず、よこ並びするul要素にcolumnsプロパティを指定して、li要素の隙間はcolumn-gapプロパティに置き換えてゆきます。
.menu-list {
columns: 3;
column-gap: 32px;
}
@media screen and (max-width: 767px) {
.menu-list {
column-gap: 16px;
}
}
@media screen and (max-width: 414px) {
.menu-list {
columns: 2;
column-gap: 8px;
}
}
商品一覧の並び順が他のレイアウトと違うのは、やはりあくまで“段組”だから。なんたって成り行きなので、横方向の画像の位置を揃えるのは難しそうですね…。
けれど、商品一覧の商品説明が、文章の途中で次の列に分割されるのは避けたいです。ということで、ここでもpage-break-insideプロパティの出番です。商品一覧のli要素の途中では改ページしないように指定します。
.menu-list li {
page-break-inside: avoid;
}
サイドメニューの横幅が広くなったので、記事一覧は最初から4つ並びにして、li要素の隙間も狭めに調整します。最後のバナーも最初からよこ並びでよいかも。
記事一覧が、画面幅によって、2つめで改列したり改列しなかったりしてます。商品一覧みたく、li要素の途中で改列されちゃっているわけではないので、break-insideプロパティではなくて、break-afterプロパティというのを使って、li要素の後の改列具合を制限することにします。この値にcolumn
という値を指定すれば、その要素の後で、必ず改ページするようになるはずです。
一方Firefoxでは、商品一覧の改列する位置がいざこざしてます。li要素に加えて、li要素の子要素にもpage-break-inside: avoid
を指定してみます。
いろいろ不具合もあるし、成り行きゆえに微調整が効かないのが難点ですね…。そもそもページレイアウトするためのプロパティではないことを忘れてはいけません…X|。
文章中に画像があるところとお知らせ一覧
ひとまずcolumnsプロパティを指定してみると、下のサンプルのようになりました。
.column-layout {
columns: 2;
column-gap: 32px;
}
.info-list {
columns: 3;
column-gap: 16px;
}
お知らせ一覧は案の定という感じだけれど、文章中に画像があるところは、文章量のおかげもあるかもしれませんけれど、ちょうどいい感じに2列に分けられてるので、この際、画像回り込みはやめて、2段組レイアウトにしちゃおうと思います。お知らせ一覧はやっぱり見にくいので元に戻しますX)。
画像は各列の横幅いっぱいに広げて、画像と文章の間に余白をつけて、列と列の間には仕切り線を入れてみようと思います。column-ruleプロパティでかんたんに仕切り線を入れられるのが、カラムレイアウトの素敵ポイントですよね。メインコンテンツの最初の文章のところも、同じ2段組に合わせておきましょう。
414px以下の時には2段組だと余計読みづらいからcolumns: 1
にして、できあがり!
.column-layout {
columns: 2;
column-gap: 32px;
column-rule: 1px solid #dcdcdc;
}
.column-layout img {
display: block;
width: 100%;
margin: 1em 0;
}
.column-layout img:first-child {
margin-top: 0;
}
@media screen and (max-width: 414px) {
.column-layout {
columns: 1;
}
}
フッターのサイトマップ
ここも例によって、単純に、ul要素にcolumnsプロパティを指定して、隙間をcolumn-gapプロパティで空けるようにします。
@media print, (min-width: 768px) {
.sitemap-list {
columns: 5;
column-gap: 16px;
}
}
なんだかとっても綺麗にレイアウトされましたね…!あとは改列する位置を制限すれば、全部うまくいきそうです。.sitemap-list .group
にpage-break-insideプロパティを指定します。
すると下のサンプルのように、なんの問題もなくレイアウトできちゃいました!
@media print, (min-width: 768px) {
⋮
.sitemap-list .group {
page-break-inside: avoid;
}
}
Comment & Pingback