Help us understand the problem. What is going on with this article?

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

背景

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

良記事

利用ツール

Syncer - CSSのコード整形ツール

比較

1. Bootstrap 4.3

参考サイト

特徴

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

.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 )
    各解像度に合わせたclass名がある ( sm, md, lg, xl )
.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

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

: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

.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

参考サイト

特徴

  • 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 クラス名 の接頭辞には is-has- を付ける

.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 ~

* v0.7.5 からブレイクポイントが上記に変更

.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 クラスの利用が多い。

.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;  }
<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 種類
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

.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; }

その他 特徴的個別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

参考サイト

特徴

breakpoint

color

その他 特徴的個別CSS

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした