Flexboxを使って表を作ってみよう。~隣接した線が重なり太くなる現象を解消しよう編~

はじめに

今回はflexboxを作って表を作る方法を紹介します。
flexboxは本来、HTMLとCSSを使って要素を横並びさせるためのレイアウト方法ですが、
使いこなすことで様々なデザインに応用することができます。
たとえば、CSSでdisplay: flex;を指定するだけで、HTMLの要素を「flex(柔軟)」に配置できるのが特徴です。
flexboxを使う上でつまずくポイントの一つである隣接した線が重なる、または、2重になって太くなる現象の解消法を重点的に解説していこうと思います。

社員ID
社員名
部署
担当
1
山田太郎
開発
ソフト
2
山田花子
経理
事務

改善前レイアウト

社員ID
社員名
部署
担当
1
山田太郎
開発
ソフト
2
山田花子
経理
事務

改善後レイアウト

隣接した線が重なる現象、解消パターン2選

  1. outline + background-color + overflowの重ね技で要らない線を目立たなくする。
  2. 隣接するborderの片方の線だけ消す。

今回は1番の方法を解説します。

outline + background-color + overflowの重ね技で要らない線を目立たなくする

borderではなく、outlineを採用した方法になります。
ここでざっくりとborderとoutlineの違いについて解説していこうと思います。

outlineは要素の外側に線を引き、線自体に領域を持たずあくまで、見た目だけです。
そのため、レイアウトが崩れにくいというメリットがある一方、四方向未満の線が引けないといったデメリットがあります。

それに対してborderは要素の内側に線を引き、線自体にも領域を持ちます。
そのため、レイアウトは崩れやすいというデメリットがある一方、上下、左右どの方向にも線を引いたり、引かなかったりできるというメリットをもっています。

尚、outlineはoutline-offsetを使うことで内側に線を引くことができます。

以下、htmlコード

    <div class="container">
        <div class="table">
            <div class="row header">
                <div class="cell">
                    <span> 社員ID</span>
                </div>
                <div class="cell">
                    <span> 社員名</span>
                </div>
                <div class="cell">
                    <span> 部署</span>
                </div>
                <div class="cell">
                    <span> 担当</span>
                </div>
            </div>
            <div class="row">
                <div class="cell">
                    <span class="item"> 1</span>
                </div>
                <div class="cell">
                    <span class="item"> 山田太郎</span>
                </div>
                <div class="cell">
                    <span class="item"> 開発</span>
                </div>
                <div class="cell">
                    <span class="item"> ソフト</span>
                </div>
            </div>
            <div class="row">
                <div class="cell">
                    <span class="item"> 2</span>
                </div>
                <div class="cell">
                    <span class="item"> 山田花子</span>
                </div>
                <div class="cell">
                    <span class="item"> 経理</span>
                </div>
                <div class="cell">
                    <span class="item"> 事務</span>
                </div>
            </div>
        </div>
    </div>

以下、css

.container{
    display: flex;
    justify-content: center;
    min-width: 0px;
}
.table {
    background-color: white;
    box-sizing: border-box;
    outline: 1px solid black;
    outline-offset: -1px;
    overflow: auto; //後々、スクロールを実装したい場合は、auto、実装しない場合はhidden
    margin: 5px;
    max-width: 600px;
    width: 100%;
}
.row {
    display: flex;
    width: 100%;
}
.cell {
    display: flex;
    flex: 1;
    box-sizing: border-box;
    min-width: 0px;
    justify-content: center;
    align-items: center;
    width: 100%;
    min-height: 40px;
    outline: 1px solid black;
    outline-offset: 0px;
    background-color: white;
    margin: 0px;
}

.header .cell {
    background-color: orange;
}
.item{
  //項目を編集したい場合に使用
}

コードの解説をしていきます。
ポイントは3つです。

  • outlineを使う。
  • セルに背景色を適用する。
  • 行とセルを囲む枠に対して、overflowを適用する。

まず、outlineを使うに関しては前述した通り、線が持つ領域によるレイアウト崩れを防ぐためです。

次に、セルに背景色を適用するに関して、outlineを適用しただけでは、まだ線が2重に重なってしまいますが、背景色を適用することによって、線の要らない部分が背景色によって上書きされるため、あたかも、1つの線を引いてるかのようにみせることができます。
※outline-offsetで内側、または外側に引いた場合は、表示されます。

最後に、行とセルを囲む枠に対して、overflowを適用するに関してですが、これはクリッピング(切り取り)というwebデザインテクニックに由来するところから来ています。

※クリッピングとは?
クリッピングとは、グラフィックやUIデザイン、ウェブページのレンダリングなどで、特定の領域の外にある描画部分を見えなくしたり、表示しないようにする技術です。これにより、描画や表示の範囲を制御することで、余計な表示を防ぐことができます。たとえば、写真や図形の一部だけを表示したり、スクロール可能なエリア内で内容を切り取るときなどに使われます。

overflowはスクロールを実装するためのcssプロパティですが、そのプロパティ値であるautoやhidden、scrollなどにはクリッピングの性質も含まれます。なので、スクロールにも対応できてクリッピングもできる一石二鳥のcssプロパティとして扱うことができます。
今回の場合では枠をはみ出たセルの線を消す役割を担っています。

おわりに

Flexboxは非常に幅広い表現ができるレイアウト方法であり、レスポンシブデザインの実装にも適した技術です。
一般的に、SEO対策の観点から表の作成にはテーブルレイアウトが多く採用されますが、flexboxを使うことにも多くのメリットがあります。
テーブルレイアウトに比べて柔軟なレイアウトが可能であり、標準的な表では表現しにくいデザインや、条件によるデザインの切り替え、
カードビューの実装、表示順の並べ替えなどをシンプルに行えます。
また、flex-directionを活用することで、縦並びや横並びを指定し、縦結合や横結合を疑似的に再現することが可能です。
自分の環境や用途に応じて、テーブルレイアウトとflexboxを使い分けることが重要です。

よかったらシェアしてね!