LogoMark.png

CSS/Flexbox の変更点


#author("2019-07-05T02:25:38+00:00","default:inoue.ko","inoue.ko")
*CSS|Flexbox
~

Flexboxとは柔軟なレイアウトを実現できるCSS3のレイアウトモジュールです。複雑なレイアウトを少ないコードで実装することができます。例えば、サイトナビゲーションメニューを横に並べる場合、float プロパティを使うよりも Flexbox を使う方が簡単にそれを実現できます。

仕様の変更、ブラウザの未対応など、これまで不安要素があったのですが、2018年現在では Firefox、Chrome、Safar、いずれもベンダープレフィックス無しで、大半のプロパティーを正しく認識するようになっています。

-W3Cの記事:https://www.w3.org/TR/css-flexbox/#box-model
-ブラウザの対応状況:http://caniuse.com/#search=flexbox
~

//***CONTENTS
//#contents2_1
//~
//#hr
~


***Flexboxの仕様
Flexbox の考え方を一言でまとめると、以下のようになります。
 親要素(Flexコンテナ) に display: flex; を設定すると
 子要素(Flexアイテム) の 並び(縦・横)や順序(上下・左右)について、
 様々なプロパティを設定しつつ自由にレイアウトできる

以下、メニューを横に並べる・・という簡単な事例です。
-HTML
 <ul>
   <li><a href="#">about</a></li>
   <li><a href="#">gallery</a></li>
   <li><a href="#">links</a></li>
 </ul>
-CSS
 ul {
   display: flex;
   flex-direction: row;
 }
 li {
   width: 120px;
   margin-right: 20px;
 }
要するに親要素に対して、display: flex; と書けば、子要素は横や縦に並ぶように制御することができます。
~

一般的には、以下のようにコンテナとアイテムを Classで定義します。
-HTML
 <div class="flex-container">
   <div class="flex-item"> 〜 </div>
   <div class="flex-item"> 〜 </div>
   <div class="flex-item"> 〜 </div>
   <div class="flex-item"> 〜 </div>
     :
 </div>
-CSS
 .flex-container {
   display: flex;
   flex-direction: row;
 }
 .flex-item {
  ・・略・・
 }
~

モバイルサイズではメニューを flex-direction: column; 、PCサイズの場合は flex-direction: row;  といった使い方で、レスポンシブデザインも簡単です。

~



***Flexコンテナのプロパティー
コンテナとなるボックスに指定するプロパティ
-''flex-direction'':Flexアイテムの向き・方向
row(左から右へ) / row-reverse(右から左へ) / 
column(上から下へ)  / column-reverse(下から上へ) 
-''flex-wrap'':幅が不足した場合にFlexアイテムの折り返しを認めるか否か
nowrap(なし)/ wrap(下へ折り返し) / wrap-reverse(上へ折り返し)
-''flex-flow'':flex-directionとflex-wrapをまとめて設定するショートハンド
-''justify-content'':Flexアイテム同士の余白の調整
flex-start(左) / flex-end(右) / center(中央) / space-between(均等)
space-around 	均等配置(先端・終端にも余白)
-''align-items'':Flexアイテムの垂直揃え
flex-start(横配置の場合は上、縦配置の場合は左) /  
flex-end (横配置の場合は下、縦配置の場合は右) / 
center(中央) / baseline(ベースライン) / stretch(等幅)
-''align-content'':複数行のFlexアイテムの揃え方
stretch(全体幅) / flex-start(横配置の場合は上、縦配置の場合は左) / flex-end(横配置の場合は下、縦配置の場合は右) / center(中央) / space-between(	均等) / space-around(均等、先端・終端にも余白)
~

***Flexアイテムのプロパティー
-''flex-grow'':コンテナに空きがある場合のアイテムの伸長率
//以下の例では、boxA:boxB:boxC = 1:2:3 の比率になります。
// .flex-container { display: flex; }
// .boxA { flex-grow: 1; }
// .boxB { flex-grow: 2; }
// .boxC { flex-grow: 3; }
-''flex-shrink'':コンテナ幅が不足する場合のアイテムの萎縮する割合を調整
-''flex-basis'':Flexアイテムの基準幅(最小幅)
auto (自動) /  単位を含めた数値
-''align-self'':個々のFlexアイテムの垂直揃え
auto (自動)  / flex-start(横配置の場合は上、縦配置の場合は左) / 
flex-end(横配置の場合は下、縦配置の場合は右) / 
center(中央) / baseline(ベースライン) / stretch(全体を等幅)
-''order'':Flexアイテム個々の並び順
Flexアイテムの個々の順番を設定(デフォルト値は0)
-''flex'':flex-grow、flex-shrink、flex-basisのショートハンド
デフォルト値は 0 1 auto
~

***Flexアイテムの幅について
以下の例では、BOXが2つ横に2:1の比率で並びます。
 <div class="flex-container">
   <div class="flex-a">
     <p>BOX-A</p>
   </div>
   <div class="flex-b">
     <p>BOX-B</p>
   </div>
 </div>

 .flex-container{  display: flex; width:960px; } 
 .flex-a { flex-grow: 2;  }
 .flex-b { flex-grow: 1;  }
~

flex-basisが定義されている場合、2つのブロック幅は以下のようになります。
 Aの幅 = Aのbasis値 + ( 2 × ( 960px – ABのbasis合計)  ÷  ( 2+1 ) )
 Bの幅 = Bのbasis値 + ( 1 x ( 960px – ABのbasis合計)  ÷  ( 2+1 ) )
~

flex-basisが0であれば話はシンプルで、以下のように単純に2:1になります。
 Aの幅 = 0 + ( 2 × ( 960px – 0 ) ÷ ( 2+1 ) ) = 640px
 Bの幅 = 0 + ( 1 × ( 960px – 0 ) ÷ ( 2+1 ) ) = 320px
~

ちなみに flex というショートバンドで、{ flex: 2; } と書いた場合、flex-grow は 2 に、flex-basis は 0 となります。よって、以下のように書くだけでも、2つのアイテム幅は2:1になります。
 .flex-container { display: flex; }
 .flex-a { flex: 2; }
 .flex-b { flex: 1; }
~

***Flexアイテムがはみ出す問題について
Flexアイテムには、width: 70%; などと指定しても、大きな画像や、英文がはみ出す・・という問題があります。

width:700px; という明示的な幅指定があれば、内容がはみだすことはありあせんが、width: 70%; と書くと、サイズが明示的ではないので、内容にそれより大きな画像があるとはみ出す・・ということになるようです。

フレキシブルにしたいということは、明示的なサイズは書きたくないわけで、ではどうすれば?・・ということになるのですが、答えは以下。

Flex アイテムが水平方向に並ぶ場合の最小幅は、アイテムの内容の最小幅または Flex アイテムに width プロパティで明示的に指定された幅などのうち、最も小さい値が選択される。''つまり、Flex アイテムの幅はそこまでは縮むことができる・・''ということです。よって、実質的にレイアウトに影響のない、min-widthの方に以下のような明示的な指定を行って、そこまでは縮んでもいい・・ということにすれば解決します。
 min-width: 100px; 
逆説的でややこしいのですが、現状そうなるようです。

&aname(sample);
~

***Flexbox サンプル1 → [[DEMO>https://koichi-inoue.github.io/Flexbox01/]]
header、nav ul、main の3箇所がFlexコンテナになっています。
-HTML
 <!DOCTYPE html>
 <html lang="ja">
 
 <head>
     <meta charset="UTF-8">
     <link rel="stylesheet" href="style.css">
     <title>Sample Site</title>
 </head>
 
 <body>
   <div id="container">
 
     <header>
         <h1>header</h1>
         <nav>
             <ul>
                 <li><a href="#">about</a></li>
                 <li><a href="#">gallery</a></li>
                 <li><a href="#">links</a></li>
             </ul>
         </nav>
     </header>
 
     <main>
 
       <article>
         article
       </article>
 
       <aside>
         aside
       </aside>
 
     </main>
 
     <footer>
        &copy; http://www.example.com
     </footer>
 
   </div>
 </body>
 </html>
~

-CSS
 *{
   margin: 0;
   padding: 0;
   list-style: none;
   text-decoration: none;
 }
 
 #container {
   width: 84%;
   max-width: 1280px;
   min-width: 512px;
   margin: 0 auto;
 }
 
 header {
   display: flex;
   padding: 40px;
   background: #333;
 }
 
 header h1{
   margin-right: auto;
   color: white;
 }
 
 header nav ul{
   display: flex;
   flex-direction: row;
 }
 
 header nav ul li{
   margin-right: 24px;
 }
 
 main{
   display: flex;
 }
 
 article{
   flex: 3;
   height: 400px;
   padding: 40px;
   background: #EEE;
 }
 
 aside{
   flex: 1;
   padding: 40px;
   background: #DDD;
 }
 
 footer {
   padding: 40px;
   text-align: center;
   background: #333;
   color: white;
 }
~
~

***サンプル2 → [[DEMO>https://koichi-inoue.github.io/Flexbox02/]]
メディアクエリーを使わずに Flexbox のみでスマホに対応させる事例です。以下、フレキシブルに横と縦を切り替える <article> 部分のみを掲載します。全体像はDEMOページから辿ってご覧下さい。

-HTML
 <article>
   <div class="imageBox">
     <img src="images/sample.jpg">
   </div>
   <div class="textBox">
      <h2>Dummy Text</h2>
      <p>A wonderful serenity </p>
   </div>
 </article>

-CSS
 article {
   display: flex;
   flex-wrap: wrap;
 }
 
 .imageBox{
   flex: 1;
   text-align: center;
   flex-basis:200px;
 }
 
   .imageBox img{
     width: 80%;
   }
 
 .textBox{
   flex: 3;
   flex-basis:400px;
 }
 
   .textBox h2 {
     width: 80%;
     margin: auto;
   }
 
   .textBox p{
     width: 80%;
     margin: auto;
     text-align: justify;
   }

-article がFlexコンテナで、その中の2つの div が Flexアイテムです。
-flex-wrap: wrap; とあることで、横幅が不足した場合に折返しとなります。
-左のBoxで flex: 1; 右のBoxで flex: 3; とすることで、横並びレイアウトにおいては、1:3の比率に保たれます。
-各Boxのサイズは flex-basis に記載された幅を保持します。この記載がないと、どこまでも細長くなって、折り返しが生じません。

~
~
~