HTML/CSS初心者から中級者への一歩を踏み出す練習課題 その４

[その３](https://qiita.com/yanda/items/8cc43ded868fbf953676)では、与えられた[課題](https://qiita.com/yanda/items/3a99891f03e9e84ceed8#%E8%AA%B2%E9%A1%8C)をついにクリアし、しかも急な[追加要求](https://qiita.com/yanda/items/8cc43ded868fbf953676#%E8%BF%BD%E5%8A%A0%E8%A6%81%E6%B1%82)までこなすことができました。
これであなたも立派なフロントエンドエンジニア、とはすぐにはいきません。

IE11での評価はしましたか？

# さあIE対応だ
IE11のサポートが切れた未来にこれを読んでいる人にこの記事は必要ありません。
きっと素敵な世の中になっていることでしょう。

さて2018年現在、IE11をサポートしなければいけない現場がほとんどでしょう。
もしサポートはChromeだけでいいよと言われている幸運な人がいたらその人もこの記事を読む必要はありません。
これまではChromeなどのモダンブラウザで表示確認をしてきたと思いますが、今度はWindowsのIE11で確認してみてください。　　

きっとどこか崩れたでしょう？
筆者の[コード例](https://github.com/yonda-yonda/html-css-bootcamp/tree/master/stage5)も見事にIE11で崩れています。PCサイズで確認していますが、まるでSP時のような縦積みになってしまっています。
![ie.png](https://qiita-image-store.s3.amazonaws.com/0/203034/7b8b87c1-5558-276b-217e-846485a215fe.png)

みなさんも自分のコードを直してみましょう（もし崩れてる部分が1つもない人はすごいです。初心者なんて謙遜せず胸を張って中級者以上を名乗ってください）。
もしどうしても直すことができなければJavascriptで直すことも考えてみてください。

## IEバグと戦う
筆者の作成例ではflexboxを多用していますが、IEにはflexboxのバグがたくさんあります。
[flexboxのバグに立ち向かう（flexboxバグまとめ）](https://qiita.com/hashrock/items/189db03021b0f565ae27)

今回ひっかかったバグは以下です。

* flexのショートハンドでflex-basisにcalcを使うとが正しく計算されない。
* flexbox要素がborderやpaddingを持つとflex-basisが正しく計算されない

### flexのショートハンドでflex-basisにcalcを使うとが正しく計算されない

```
flex: 0 0 calc(33.3% - 20px);
```

このようにショートハンド形式でflex-basisにcalcを使うとIEでは崩れてしまいます。
解決策はショートハンドでなくプロパティをそれぞれ記載すること。

```style.css
.panels__item {
    flex-grow: 0;
    flex-shrink: 0; 
    flex-basis: calc(33.3% - 20px);
}
```

### flexbox要素がborderやpaddingを持つとflex-basisが正しく計算されない
解決策は2つ

* paddingとborderの値をflex-basisの値に含ませる。
* flexbox要素にborderやpaddingを設定せず小要素側に持たせる。

前者では横並びにするクラスとパネルのクラスが分離できず設計上好ましくないです。
よって後者の方針で解決します。  

paddingは`.panels__item`の子要素に持たせることでIEでも正しく表示されるようにします。
そのために`.panel`を`.panels__item`と分離します。
単純に分離すると高さが揃わなくなるので、`.panel`に`height: 100%;`を追加します。
一昔前はこれはうまく機能しなかったのですが、仕様が変わったおかげで簡単にflexboxの孫要素の高さを揃えることができるようになりました。[stackoverflow:　flexboxの孫要素にheight:100%が効かない理由はなぜですか
](https://ja.stackoverflow.com/questions/21422/flexbox%E3%81%AE%E5%AD%AB%E8%A6%81%E7%B4%A0%E3%81%ABheight100%E3%81%8C%E5%8A%B9%E3%81%8B%E3%81%AA%E3%81%84%E7%90%86%E7%94%B1%E3%81%AF%E3%81%AA%E3%81%9C%E3%81%A7%E3%81%99%E3%81%8B)

borderも`.panel`をflexboxの孫要素にしたおかげでflex-basisの計算に影響しなくなりました。

どうしてもflexboxの子要素にborderをつけないといけない場合は、borderをもたせたafter要素を`position: absolute`で浮かせ、パネルの全域に広げることで見栄えを再現しつつIEでも正しく表示されるようになります（ハックがすぎているキライはある）。

flexboxの子要素にborderをもたせる例

```index.html
<li class="panels__item　panel">
      <div class="panel__content">
          <div class="panel__content__icon">
              <img src="dummy.png" alt="ダミー">
          </div>
          <div class="panel__content__item">
              <div class="panel__title">タイトル1</div>
              <div class="panel__text">
                  テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
              </div>
          </div>
      </div>
      <div class="panel__footer">
          <ul>
              <li>補足補足補足補足</li>
              <li>補足補足</li>
          </ul>
      </div>
</li>
```

```style.css
.panel {
    position: relative;
    background-color: #fff;
    border-radius: 8px;
}

.panel::after {
    content: '';
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    border: solid 1px #cecece;
    border-radius: 8px;
}

.panel--highlight::after  {
    border: solid 2px #3176d5;
}

.panel__content {
    padding: 20px 20px 0;
}

.panel__footer {
    padding: 0 20px 20px;
}
```

[コード例](https://github.com/yonda-yonda/html-css-bootcamp/tree/master/stage6)


これで無事課題をすべてクリアすることができました。
ここまでやって以下の目標を達成できたでしょうか

* BEM記法に慣れる。
* パーツ同士が疎結合なクラス設計を意識できるようになる。
* 保守性を大事にするマインドを身につける。

全部終えた上で、もう一度はじめから作り直してみるのもいい練習となるでしょう。
この課題を足がかりに経験を積んで自分なりのノウハウを増やして中級者、上級者へと駆け上ってください。

素敵なフロントエンドエンジニアライフを！