CSSフレームワーク設計比較 [wip]

# 背景

CSSフレームワークは
CSS編集せず HTMLのみで意図されたWEBデザインを構築できる
CSS完成形の一つであり 必然的にリファクタリングされているため
CSS設計を考察するにあたり 命名規則など参考になるので比較してみた。


# 良記事

- [CSSフレームワーク30選！デザイン含めて一括総まとめ - 2019/8/12 - エンジニアの入り口
](https://eng-entrance.com/css-framework)
    - 30にも及ぶ各フレームワークのビジュアル例も載っており分かりやすく素晴らしい！
- [CSSフレームワーク一覧【2018年12月投稿】- Qiita](https://qiita.com/shin1rok/items/bdb26b2fa58fe9d30021)
    - GitHub Starでの比較がありシンプルで説得力があります。
- [厳選！軽量で使いやすいCSSフレームワーク10選【2019年最新】- Web Design Trands](https://webdesign-trends.net/entry/2177)
- [【2019年度版】ソフトウェア開発に欠かせない軽量で扱いやすい、人気CSSフレームワーク10選 - 2019/3/19 - SeleQt](https://www.seleqt.net/programming/css-frameworks-2019/)
- [レスポンシブで軽量な20のCSSフレームワーク ( 海外記事 ) - 2019/1/8 - UX Milk](https://uxmilk.jp/75765)
- [より良いCSSを書くための様々なCSS設計まとめ - 2017/7/27 - UX Milk](https://uxmilk.jp/43386)
- [メンテナンス性に優れ、拡張性を備えたCSSを書くために メンテナブルCSS - 2016/4/21 - coliss](https://coliss.com/articles/build-websites/operation/css/maintainable-css-by-adam.html)
- [CSSフレームワークを採用するべきかしないべきか、メリットやデメリット等の考察 - 2019/5/11 - high five create](https://highfivecreate.com/blog/job/4016.html)

# 利用ツール

[Syncer - CSSのコード整形ツール](https://lab.syncer.jp/Tool/CSS-PrettyPrint/)


# 比較


# 1. Bootstrap 4.3

### 参考サイト
- Official - https://getbootstrap.com/
- [GitHub - SCSS](https://github.com/twbs/bootstrap/tree/master/scss)
- [GitHub - bootstrap.css](https://github.com/twbs/bootstrap/blob/master/dist/css/bootstrap.css) - 9354 lines
- [CDN - 4.3.1/css/bootstrap.min.css](https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css)
- [日本語解説 - Bootstrap4 移行ガイド ](https://cccabinet.jpn.org/bootstrap4/) 


### 特徴 

- 最も有名で利用されているフレームワーク
- コード量が多く、動作が重い。しかし利用者が多いためドキュメントは豊富
- モバイルファーストで MediaQuery が指定されている。
- マルチクラス
- 利用時は<br> `<div class="container"> <div class="row"> <div class="col">` <br>3つの入れ子htmlから始まり、Flexboxでレイアウト構築している。

```css 
.container {
  width: 100%;
  padding-right: 15px;
  padding-left: 15px;
  margin-right: auto;
  margin-left: auto
}
@media (min-width:576px) {  .container {    max-width: 540px  }}
@media (min-width:768px) {  .container {    max-width: 720px  }}
@media (min-width:992px) {  .container {    max-width: 960px  }}
@media (min-width:1200px) { .container {    max-width: 1140px }}
.row {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  margin-right: -15px;
  margin-left: -15px
}
.col-6 {
  -ms-flex: 0 0 50%;
  flex: 0 0 50%;
  max-width: 50%
}
```

- デフォルトCSSに、12列グリッドを基準に4つのブレイクポイントに合わせ flex が細かく指定されておりレイアウトの変更が容易
- **font-size / padding / margin / border-radius** は殆ど **rem** 単位 ( classによって時々 em や px )
- **width** は % も px も rem も万遍なく使われている
- **!important** は個別指定class用に、詳細度を極力高くするため殆どファイル後方(6207行目以降)で設定されている。

```CSS
.align-baseline {  vertical-align: baseline!important }
.bg-primary {  background-color: #007bff!important }
.border {  border: 1px solid #dee2e6!important}
.d-none {   display: none!important }
.d-inline { display: inline!important }
.d-inline-block {  display: inline-block!important }
.d-block {  display: block!important }
.d-flex {   display: -ms-flexbox!important;
            display: flex!important }
@media (min-width:576px) {
  .d-sm-none {    display: none!important  }
  .d-sm-inline {  display: inline!important  }
  .d-sm-inline-block {  display: inline-block!important  }
  .d-sm-block {  display: block!important  }
  .d-sm-flex {   display: -ms-flexbox!important;
                 display: flex!important  }
}
```

- "-" ハイフン1つ区切りのみ。"--" ハイフン2つや、"_" アンダーバーは使っていない

- 各コンポーネントは、ベースは layout と color が 同じクラス内で定められているが、詳細度(高)の個別指定classを当てることにより、カスタマイズが可能な設計となっている。
例 : [button](https://cccabinet.jpn.org/bootstrap4/components/buttons)

```css 
.btn {
  display: inline-block;
  font-weight: 400;
  color: #212529;
  text-align: center;
  vertical-align: middle;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  background-color: transparent;
  border: 1px solid transparent;
  padding: .375rem .75rem;
  font-size: 1rem;
  line-height: 1.5;
  border-radius: .25rem;
  transition: color .15s ease-in-out, background-color .15s ease-in-out,
              border-color .15s ease-in-out, box-shadow .15s ease-in-out }
.btn:hover {
  color: #212529;
  text-decoration: none }
.btn-lg {
  padding: .5rem 1rem;
  font-size: 1.25rem;
  line-height: 1.5;
  border-radius: .3rem }
.btn-primary {
  color: #fff;
  background-color: #007bff;
  border-color: #007bff }
.btn-primary:hover {
  color: #fff;
  background-color: #0069d9;
  border-color: #0062cc }
```

### breakpoint

- breakpointは4つ ( 576px, 768px, 992px, 1200px ) <br> 各解像度に合わせたclass名がある ( sm, md, lg, xl )

```css
.text-left {  text-align: left!important   }
@media (min-width:576px) { .text-sm-left { text-align: left!important }}
@media (min-width:768px) { .text-md-left { text-align: left!important }}
@media (min-width:992px) { .text-lg-left { text-align: left!important }}
@media (min-width:1200px){ .text-xl-left { text-align: left!important }}
```


### color<br>
rootで各colorが変数化されています。種類は14色。<br>何故か各classで変数が使われていない理由は不明。

```css
:root {
  --blue: #007bff; 	/* primary */
  --indigo: #6610f2;
  --purple: #6f42c1;
  --pink: #e83e8c;
  --red: #dc3545;	/* danger */
  --orange: #fd7e14;
  --yellow: #ffc107;/* warning */
  --green: #28a745; /* success */
  --teal: #20c997;
  --cyan: #17a2b8;	/* info */
  --white: #fff;
  --gray: #6c757d;	/* secondary */ 
  --gray-dark: #343a40; /* dark */
  --primary: #007bff;
  --secondary: #6c757d;
  --success: #28a745;
  --info: #17a2b8;
  --warning: #ffc107;
  --danger: #dc3545;
  --light: #f8f9fa;
  --dark: #343a40;
}
.text-primary {  color: #007bff!important } 
```

### その他 特徴的個別CSS

```css
.border {  border: 1px solid #dee2e6!important}
.border-top {  border-top: 1px solid #dee2e6!important}
.border-top-0 {  border-top: 0!important}
.border-primary {  border-color: #007bff!important}
.rounded-sm {  border-radius: .2rem!important}
.rounded {  border-radius: .25rem!important}
.rounded-circle {  border-radius: 50%!important}
.clearfix::after {  display: block;  clear: both;  content: "" }
.flex-row {  -ms-flex-direction: row!important;
             flex-direction: row!important }
.flex-column {  -ms-flex-direction: column!important;
                flex-direction: column!important }
.flex-wrap {  -ms-flex-wrap: wrap!important;
              flex-wrap: wrap!important }
.flex-grow-1 {  -ms-flex-positive: 1!important;
                flex-grow: 1!important }
.justify-content-center {  -ms-flex-pack: center!important;
                           justify-content: center!important }
.justify-content-between {  -ms-flex-pack: justify!important;
                            justify-content: space-between!important }
.align-items-center {  -ms-flex-align: center!important;
                       align-items: center!important }
.align-content-center {  -ms-flex-line-pack: center!important;
                         align-content: center!important }
.align-self-center {  -ms-flex-item-align: center!important;
                      align-self: center!important }
.float-left {  float: left!important }
.float-right {  float: right!important }
.position-static {  position: static!important }
.position-relative {  position: relative!important }
.position-absolute {  position: absolute!important }
.position-fixed {  position: fixed!important }
.position-sticky {  position: -webkit-sticky!important;
                    position: sticky!important }
.fixed-top {  position: fixed;  top: 0;  right: 0;  left: 0;  z-index: 1030 }
.fixed-bottom {  position: fixed;  right: 0;  bottom: 0;  left: 0;  z-index: 1030 }
.w-50 {  width: 50%!important }
.h-100 {  height: 100%!important }
.mw-100 {  max-width: 100%!important }
.mw-100 {  max-width: 100%!important }
.mh-100 {  max-height: 100%!important }
.min-vw-100 {  min-width: 100vw!important }
.min-vh-100 {  min-height: 100vh!important }
.vw-100 {  width: 100vw!important }
.vh-100 {  height: 100vh!important }
.m-0 {  margin: 0!important}
.mt-1, .my-1 {  margin-top: .25rem!important}
.mr-2, .mx-2 {  margin-right: .5rem!important}
.mb-3, .my-3 {  margin-bottom: 1rem!important}
.ml-4, .mx-4 {  margin-left: 1.5rem!important}
.m-5 {  margin: 3rem!important}
.p-0 {  padding: 0!important}
.m-n3 {  margin: -1rem!important}
.text-monospace { font-family: SFMono-Regular, Menlo, Monaco, Consolas, 
                  "Liberation Mono", "Courier New", monospace!important }
.text-center {  text-align: center!important}
.font-weight-bold {  font-weight: 700!important}
.font-italic {  font-style: italic!important}
.text-white {  color: #fff!important}
.text-primary {  color: #007bff!important}
a.text-primary:focus, a.text-primary:hover {  color: #0056b3!important}
.text-body {  color: #212529!important}
.text-black-50 {  color: rgba(0, 0, 0, .5)!important}
.text-decoration-none {  text-decoration: none!important}
.text-break {  word-break: break-word!important;
               overflow-wrap: break-word!important}
.text-reset {  color: inherit!important}
```

# 2. Bulma

### 参考サイト
- Official - https://bulma.io
- Official - [Modifiers Syntax](https://bulma.io/documentation/modifiers/syntax/)
- GitHub - https://github.com/jgthms/bulma
- [GitHub - bulma.css](https://github.com/jgthms/bulma/blob/master/css/bulma.css) - 10599 lines
- [CDN - 0.7.5/css/bulma.css](https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.css)
- [GitHub - Sass](https://github.com/jgthms/bulma/blob/master/bulma.sass)

### 特徴
- jQueryの拡張コンポーネント無し
- IE11に一部非対応
- Bootstrap と似ており、マルチクラスかつ、"_" アンダーバーを使わず "-" ハイフン1つで区切っている。
- 構成としては
    - Columns : 全体 (縦)
        - Basics / Sizes / responsiveness / Nesting / Gap / Options 
    - Layout : 列 (横)
        - Container / Level / Media / Hero / Section / Footer / Tiles 
    - Components : アイテム
        - Breadcrumb / Dropdown / Message / Navbar / Panel / Card / Menu / Modal / Pagination / Tabs
    - Elements : 部品
        - Box / Content / Icon / Notification / Table / Title / Button / Delete / Image / Progress bars / Tag 
    - Form : フォーム
        - Textarea / Checkbox / File / Input / Select / Radio 
    - Modifiers : インライン的スタイル
        - color / display / size  
        
- [Modifiers](https://bulma.io/documentation/modifiers/) クラス名 の接頭辞には **is-** か **has-** を付ける 

```css
.is-size-1 {  font-size: 3rem !important;}
.is-size-7 {  font-size: 0.75rem !important;}
.is-italic {  font-style: italic !important;}
.is-block {  display: block !important;}
.is-inline {  display: inline !important;}
.is-relative {  position: relative !important;}
.has-background-white {  background-color: white !important;  }
.has-text-black {  color: #0a0a0a !important;  }
```

### breakpoint 

https://bulma.io/documentation/modifiers/responsive-helpers/ 

各解像度に合わせた **9 種類** のclass名
    - is-flex-**mobile** : ~ 768px 
    - is-flex-**tablet-only** : 769 - 1024px
    - is-flex-**touch** : ~ 1023px 
    - is-flex-**tablet** : 769px ~ 
    - is-flex-**desktop-only** : 1024 - 1215px
    - is-flex-**desktop** : 1024px ~
    - is-flex-**widescreen-only** : 1216 - 1407px
    - is-flex-**widescreen** : 1216px ~
    - is-flex-**fullhd** : 1408px ~  
<span>* v0.7.5 からブレイクポイントが上記に変更</span>

```css
.is-flex {  display: flex !important;}
@media screen and (max-width: 768px) {
  .is-flex-mobile {  display: flex !important;  }}
@media screen and (min-width: 769px), print {
  .is-flex-tablet {  display: flex !important;  }}
```


### layout

`<div class="level"> <div class="level-item">`や
`<div class="columns"> <div class="column">`
などでFlexboxレイアウト可能。
Expo の作品を見ると .section / .container / .level クラスの利用が多い。

```css 
.section {  padding: 3rem 1.5rem; }
@media screen and (min-width: 1024px) {
  .section.is-medium {  padding: 9rem 1.5rem;  }
  .section.is-large {   padding: 18rem 1.5rem;  }}
 
.container {  flex-grow: 1;  margin: 0 auto;  position: relative;  width: auto;}
@media screen and (min-width: 1024px) {
  .container {  max-width: 960px;  }
  .container.is-fluid {  margin-left: 32px;    margin-right: 32px;    max-width: none;  }}
@media screen and (max-width: 1215px) {
  .container.is-widescreen {    max-width: 1152px;  }}
@media screen and (max-width: 1407px) {
  .container.is-fullhd {  max-width: 1344px;  }}
@media screen and (min-width: 1216px) {
  .container {  max-width: 1152px;  }}
@media screen and (min-width: 1408px) {
  .container {  max-width: 1344px;  }}

.level {  align-items: center;  justify-content: space-between;  }
.level.is-mobile {  display: flex;  }
@media screen and (min-width: 769px), print {
  .level {  display: flex;  }
  .level > .level-item:not(.is-narrow) {  flex-grow: 1;  }
}
.level-item {  align-items: center;  display: flex;  flex-basis: auto;  flex-grow: 0;
               flex-shrink: 0;  justify-content: center; }

.columns {   margin-left: -0.75rem;  margin-right: -0.75rem;  margin-top: -0.75rem;  }
.columns.is-mobile {  display: flex;  }
@media screen and (min-width: 769px), print {
  .columns:not(.is-desktop) {  display: flex;  }}
@media screen and (min-width: 1024px) {
  .columns.is-desktop {  display: flex;  }}
.column {  display: block;  flex-basis: 0;  flex-grow: 1;  flex-shrink: 1;  padding: 0.75rem;  }
```

```html 
<section class="section is-medium">
  <div class="container">
    <header class="section-header">

<div class="columns"> <!-- flex from 769px -->
  <div class="column">1</div>
  <div class="column">2</div>
</div>
<div class="columns is-mobile"> <!-- flex allways -->
  <div class="column">1</div>
  <div class="column">2</div>
</div>
<div class="columns is-desktop"> <!-- flex from 1024px -->
  <div class="column">1</div>
  <div class="column">2</div>
</div>
```

### color

https://bulma.io/documentation/modifiers/color-helpers/

カラーは **19 種類**<br>white / black / light / dark / primary / info / link / success / warning / danger / black-bis / black-ter / grey-darker / grey / grey-light / grey-lighter / white-ter / white-bis 

```css 
.has-text-success {  color: #23d160 !important; }
.has-background-success {  background-color: #23d160 !important; }
.button.is-success {  background-color: #23d160;  border-color: transparent;  color: #fff; }
.notification.is-success {  background-color: #23d160;  color: #fff; }
.table td.is-success, .table th.is-success {  background-color: #23d160;  border-color: #23d160;  color: #fff; }
.is-success.input, .is-success.textarea {  border-color: #23d160; }
.select.is-success select {  border-color: #23d160; }
.file.is-success .file-cta {  background-color: #23d160;  border-color: transparent;  color: #fff; }
.help.is-success {  color: #23d160; }
.message.is-success {  background-color: #f6fef9; }
.message.is-success .message-header {  background-color: #23d160;  color: #fff; }
.message.is-success .message-body {  border-color: #23d160;  color: #0e301a; }
.navbar.is-success {  background-color: #23d160;  color: #fff; }
.hero.is-success {  background-color: #23d160;  color: #fff; }
```

- Font / Text - https://bulma.io/documentation/modifiers/typography-helpers/


### その他 特徴的個別CSS 

```css 
.is-pulled-left {  float: left !important; }
.is-pulled-right {  float: right !important; }
.is-clipped {  overflow: hidden !important; }
.is-size-1 {  font-size: 3rem !important; }
.is-size-2 {  font-size: 2.5rem !important; }
.is-size-3 {  font-size: 2rem !important; }
.is-size-4 {  font-size: 1.5rem !important; }
.is-size-5 {  font-size: 1.25rem !important; }
.is-size-6 {  font-size: 1rem !important; }
.is-size-7 {  font-size: 0.75rem !important; }
.title.is-1 {  font-size: 3rem; }
.title.is-2 {  font-size: 2.5rem; }
.title.is-3 {  font-size: 2rem; }
.title.is-4 {  font-size: 1.5rem; }
.title.is-5 {  font-size: 1.25rem; }
.title.is-6 {  font-size: 1rem; }
.title.is-7 {  font-size: 0.75rem; }
.has-text-centered {  text-align: center !important; }
.is-italic {  font-style: italic !important; }
.has-text-weight-bold {  font-weight: 700 !important; }
.is-family-primary {  font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen",
                      "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica",
                      "Arial", sans-serif !important; }
.is-block {  display: block !important; }
.is-flex {  display: flex !important; }
.is-inline {  display: inline !important; }
.is-inline-block {  display: inline-block !important; }
.is-inline-flex {  display: inline-flex !important; }
.is-hidden {  display: none !important; }
.is-marginless {  margin: 0 !important; }
.is-paddingless {  padding: 0 !important; }

.button {  background-color: white;  border-color: #dbdbdb;  border-width: 1px;
  color: #363636;  cursor: pointer;  justify-content: center;
  padding-bottom: calc(0.375em - 1px);  padding-left: 0.75em;  padding-right: 0.75em;
  padding-top: calc(0.375em - 1px);  text-align: center;  white-space: nowrap; }
.button.is-small {  border-radius: 2px;  font-size: 0.75rem; }
.button.is-normal {  font-size: 1rem; }
.button.is-medium {  font-size: 1.25rem; }
.button.is-large {  font-size: 1.5rem; }
.button.is-fullwidth {  display: flex;  width: 100%; }
.buttons {  align-items: center;  display: flex;  flex-wrap: wrap;  justify-content: flex-start; }
.buttons .button {  margin-bottom: 0.5rem; }
.buttons:last-child {  margin-bottom: -0.5rem; }
.buttons:not(:last-child) {  margin-bottom: 1rem; }
.buttons.is-centered {  justify-content: center; }
.buttons.is-right {  justify-content: flex-end; }

.container {  flex-grow: 1;  margin: 0 auto;  position: relative;  width: auto; }
.content h1,.content h2,.content h3,.content h4,.content h5,.content h6 {
               color: #363636;  font-weight: 600;  line-height: 1.125; }
.content h1 {  font-size: 2em;  margin-bottom: 0.5em; }
.content h1:not(:first-child) {  margin-top: 1em; }
.content h2 {  font-size: 1.75em;  margin-bottom: 0.5714em; }
.content h2:not(:first-child) {  margin-top: 1.1428em; }
.content ol {  list-style-position: outside;  margin-left: 2em;  margin-top: 1em; }
.content ul {  list-style: disc outside;  margin-left: 2em;  margin-top: 1em; }
.content ul ul {  list-style-type: circle;  margin-top: 0.5em; }
.content ul ul ul {  list-style-type: square; }
.content dd {  margin-left: 2em; }

.content.is-small {  font-size: 0.75rem; }
.content.is-medium {  font-size: 1.25rem; }
.content.is-large {  font-size: 1.5rem; }

.image.is-square, .image.is-1by1 {  padding-top: 100%; }
.image.is-3by2 {  padding-top: 66.6666%; }
.image.is-16by9 {  padding-top: 56.25%; }
.image.is-2by1 {  padding-top: 50%; }
.image.is-3by1 {  padding-top: 33.3333%; }
.image.is-2by3 {  padding-top: 150%; }
.image.is-9by16 {  padding-top: 177.7777%; }
.image.is-1by2 {  padding-top: 200%; }
.image.is-1by3 {  padding-top: 300%; }
.image.is-16x16 {  height: 16px;  width: 16px; }
.image.is-128x128 {  height: 128px;  width: 128px; }

.subtitle {  color: #4a4a4a;  font-size: 1.25rem;  font-weight: 400;  line-height: 1.25; }

.level {  align-items: center;  justify-content: space-between; }
.level-item {  align-items: center;  display: flex;  flex-basis: auto;
               flex-grow: 0;  flex-shrink: 0;  justify-content: center; }
@media screen and (min-width: 769px), print {
  .level {  display: flex;  }
  .level > .level-item:not(.is-narrow) {  flex-grow: 1;  }}

.columns.is-mobile > .column.is-narrow {  flex: none; }
.columns.is-mobile > .column.is-full {  flex: none;  width: 100%; }
.columns.is-mobile > .column.is-three-quarters {  flex: none;  width: 75%; }
.columns.is-mobile > .column.is-9 {  flex: none;  width: 75%; }
.columns.is-mobile > .column.is-two-thirds {  flex: none;  width: 66.6666%; }
.columns.is-mobile > .column.is-8 {  flex: none;  width: 66.66667%; }
.columns.is-centered {  justify-content: center; }
.columns.is-gapless {  margin-left: 0;  margin-right: 0;  margin-top: 0; }
.columns.is-gapless > .column {  margin: 0;  padding: 0 !important; }

.section {  padding: 3rem 1.5rem; }
@media screen and (min-width: 1024px) {
  .section.is-medium {  padding: 9rem 1.5rem;  }
  .section.is-large {  padding: 18rem 1.5rem;  }}

```


# Foundation

### 参考サイト

- Docs - https://foundation.zurb.com/sites/docs/global.html
- CDN - https://cdn.jsdelivr.net/npm/foundation-sites@6.5.3/dist/css/foundation.css - 5577 lines




### 特徴

### breakpoint

### color
- [Docs - Global Style](https://foundation.zurb.com/sites/docs/global.html) 
- [GitHub _global.scss](https://github.com/zurb/foundation-sites/blob/develop/scss/_global.scss) (カラー変数など) 



### その他 特徴的個別CSS