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

UIコンポーネントにはマージンをつけるな!絶対にだ!!

私は長年、CSSmarginをどのように書くか悩んできました。

たとえば、このようなボタン。

<button class="button">ボタンだよ</button>
.button {
  display: block;
  margin: 50px auto 0;
  padding: 8px 20px;
  border: solid 2px #ddd;
  border-radius: 10px;
  font-size: 16px;
}

See the Pen button_01 by Otsuka Yuhi (@boltkeep) on CodePen.

パット見、いい感じのボタンです。

しかし、このボタンには一点重大な欠点があります。

それは、このボタンは必ず上に50pxの余白が付き、かつ中央寄せされるということです。

デザイナー登場

デザイナーがこう言いました。

「ボタンを横に2つ並べたい」
「ボタンとボタンの間隔は20px」
「その上で中央寄せで!」

さて、どうしましょう??display: flex;でしょうか?

<div class="flex">
  <button class="button">ボタンだよ</button>
  <button class="button">ボタンだよ</button>
</div>
.flex {
  display: flex;
}

.button {
  display: block;
  margin: 50px auto 0;
  padding: 8px 20px;
  border: solid 2px #ddd;
  border-radius: 10px;
  font-size: 16px;
}

See the Pen qBWXoWa by Otsuka Yuhi (@boltkeep) on CodePen.

。。。どうやら、.buttonからmargin: 50px auto 0;を削除しないことには無理そうです。。

しかし、このボタンはすでに別のページで使われており、margin: 50px auto 0;を削除すると、様々なページのボタンから上の余白と中央寄せが失われてしまいます。

これは非常にまずい!

影響がないように、.row-buttonをつくりましょうか。

<div class="row-buttons">
  <button class="row-button">横並びボタンだよ</button>
  <button class="row-button">横並びボタンだよ</button>
</div>
.row-buttons {
  display: flex;
  justify-content: center;
}

.row-button {
  padding: 8px 20px;
  border: solid 2px #ddd;
  border-radius: 10px;
  font-size: 16px;

  &:nth-child(n+2) {
    margin-left: 20px;
  }
}

See the Pen OJLjvyE by Otsuka Yuhi (@boltkeep) on CodePen.

なんとか難は逃れたようです。よかったよかった。

デザイナー再登場

「縦に20pxの間隔で積まれたボタンが必要です」

な、なんだと。。。

<div class="column-buttons-container">
  <div class="column-buttons">
    <button class="column-button">縦並びボタンだよ</button>
    <button class="column-button">縦並びボタンだよ</button>
  </div>
</div>
.column-buttons-container {
  display: flex;
  justify-content: center;
}

.column-buttons {
  display: inline-flex;
  flex-direction: column;
}

.column-button {
  padding: 8px 20px;
  border: solid 2px #ddd;
  border-radius: 10px;
  font-size: 16px;

  &:nth-child(n+2) {
    margin-top: 20px;
  }
}

See the Pen flex column button by Otsuka Yuhi (@boltkeep) on CodePen.

だんだんいい感じになってきましたね!\(^o^)/

.buttonにマージンがなければ問題なかった

もうお気づきかと思いますが、.buttonがマージンを持っていなければたくさんのボタン用CSSクラスは不要でした。

<button class="button">ボタンだよ</button>
.button {
  padding: 8px 20px;
  border: solid 2px #ddd;
  border-radius: 10px;
  font-size: 16px;
}

単体中央寄せ

<div class="centering">
  <button class="button">中央寄せボタン</button>
</div>
.centering {
  display: flex;
  justify-content: center;
  margin-top: 50px;
}

.button {
  padding: 8px 20px;
  border: solid 2px #ddd;
  border-radius: 10px;
  font-size: 16px;
}

See the Pen 中央センタリング上マージン by Otsuka Yuhi (@boltkeep) on CodePen.

横並び中央寄せ

<div class="row-buttons">
  <button class="button">横並びボタン</button>
  <button class="button">横並びボタン</button>
</div>
.row-buttons {
  display: flex;
  justify-content: center;

  > *:nth-child(n+2) {
    margin-left: 20px;
  }
}

.button {
  padding: 8px 20px;
  border: solid 2px #ddd;
  border-radius: 10px;
  font-size: 16px;
}

See the Pen 横並び中央寄せ by Otsuka Yuhi (@boltkeep) on CodePen.

縦積み

<div class="column-buttons-container">
  <div class="column-buttons">
    <button class="button">縦積みボタン</button>
    <button class="button">縦積みボタン</button>
  </div>
</div>
.column-buttons-container {
  display: flex;
  justify-content: center;
}

.column-buttons {
  display: inline-flex;
  flex-direction: column;

  > *:nth-child(n+2) {
    margin-top: 20px;
  }
}

.button {
  padding: 8px 20px;
  border: solid 2px #ddd;
  border-radius: 10px;
  font-size: 16px;
}

See the Pen yLBoKXL by Otsuka Yuhi (@boltkeep) on CodePen.

クラス名がダサいのはご容赦願います\(^o^)/

まとめ

今回はbuttonのみの例でしたが、ほかの要素やUIコンポーネントでもページによってマージンが違ったりするスタイルはよくあるかと思います。

デザインに柔軟に対応するためにも、UIコンポーネントにはマージンを持たせず、使う側から指定してあげるというルールを設けてあげれば、CSSが少し楽になるかもしれません。

もちろん、例外は存在しますので、例えばLPとかでそのUIにはこのマージンしか絶対に存在しないみたいなことがあれば、直接書いても良いかと思います。

それでは、また。

otsukayuhi
ゆめみ所属のフロントエンドウェブデベロッパーです。藤子・F・不二雄先生を尊敬する、キーボードマニアでもあります。
https://otsukayuhi.app/
yumemi
みんなが知ってるあのサービス、実はゆめみが作ってます。スマホアプリ/Webサービスの企画・UX/UI設計、開発運用。Swift, Kotlin, PHP, Vue.js, React.js, Node.js, AWS等エンジニア・クリエイターの会社です。東京(三軒茶屋)/京都(四条烏丸)/札幌/大阪/福岡に展開中!Twitterで情報配信中https://twitter.com/yumemiinc
http://www.yumemi.co.jp
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
ユーザーは見つかりませんでした