LoginSignup
2
5

More than 3 years have passed since last update.

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

Posted at

背景

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

カラーは 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

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5