SimpleIsm

舞台裏は乱雑に、見えるところはシンプルに。

marginとline-heightによる"真の余白"について考える

まだまだWeb制作においては、デザイナーがデザインしたものをコーダーがコーディングする、というような流れが多いように思う。

デザイナーは1pxにもこだわる人たちなので、コーダーもそれに応えるように、きちんとデザイン通りに表現する。ようにがんばっている。

「ここは20px、ここは40px、ここは60px」というような具合に、余白の指示書などがあるとありがたい。デザイナーによっては、余白がそれぞれバラバラだったりして、なかなか骨が折れることもあるので…。

例えば、「見出しの下の余白を20px空けたい」という指示があったとする。margin-bottom: 20px;でOKだけど、実はそれ、下の文章のline-heightなどによっては、きちんと20px空いてなかったりすることもある。

以下の例で考える。

:root {
    font-family: meiryo;
    font-size: 10px;
}

h1 {
    font-size: 3rem;
    line-height: 1;
    margin: 0;
}

p {
    font-size: 1.5rem;
    line-height: 1.8;
    margin: 0;
}
<body>
    <h1>margin調整について</h1>
    <p>margin調整について書きます。<br>margin調整について書きます。<br>margin調整について書きます。</p>
</body>

これの結果が以下。

margin調整について1

これのh1の下に20pxの余白を空けるため、margin-bottom: 20px;と入れてみる。で、Chromeのインスペクタで要素を確認してみる。と、若干20pxより余白が大きいように見える。

margin調整について2

そう、これは兄弟要素であるpline-height: 1.8;分の余白が追加されているためである…。

margin調整について3

じゃあ実際にそのline-height分の余白を20pxから引いてあげればいいよね!つまり、20pxから6px引いた、14pxをh1margin-bottomにしてあげればOK!

でも、それらをいちいち計算するのも面倒…。そこで、みんな大好きcalc()関数ですよ。

h1 {
    margin-bottom: calc(20px - (((1.5rem * 1.8) - 1.5rem) / 2));
}

1.5rem(今回の場合は15px)のline-height: 1.8;なので1.8倍で27pxがp要素の行の高さ。そこから自身のテキスト分1.5remを引いてあげた12px分が、均等に上下に割り振られているから、2で割った6pxがテキストの上の部分の余白になる。これを20pxから引いた数字(つまり14px)をh1margin-bottomに指定してあげれば、余白をぴったり20pxにできるという計算。

margin調整について4

margin調整について5

ね。

ただ今度は、それぞれフォントサイズや行の高さに合わせて数値を一つ一つ変えるのは面倒臭い!って思いますよね?そこで、みんな大好きSassですよ。SCSS形式で書きます。

$baseMargin: 20px;
$pFontSize: 1.5rem;
$pLineHeight: 1.8;
@mixin marginBottom($baseMargin: 20px, $pFontSize: 1.5rem, $pLineHeight: 1.8) {
    margin-bottom: calc(#{$baseMargin} - (((#{$pFontSize} * #{$pLineHeight}) - #{$pFontSize}) / 2));
}

h1 {
    @include marginBottom;
}

p {
    font-size: $pFontSize;
    line-height: $pLineHeight;
}

こうやって@mixinしてやれば初期値とかも指定できるし便利。h2の時は下の余白は40pxにしたい!しかも、次の要素の行の高さは2.2だった!なんてときも大丈夫。

$baseMargin: 20px;
$pFontSize: 1.5rem;
$pLineHeight: 1.8;
@mixin marginBottom($baseMargin: 20px, $pFontSize: 1.5rem, $pLineHeight: 1.8) {
    margin-bottom: calc(#{$baseMargin} - (((#{$pFontSize} * #{$pLineHeight}) - #{$pFontSize}) / 2));
}

h1 {
    @include marginBottom;
}

h2 {
    @include marginBottom($baseMargin: 40px, $pLineHeight: 2.2);
}

p {
    font-size: $pFontSize;
    line-height: $pLineHeight;
}

コンパイル結果。

h1 {
  margin-bottom: calc(20px - (((1.5rem * 1.8) - 1.5rem) / 2)); }

h2 {
  margin-bottom: calc(40px - (((1.5rem * 2.2) - 1.5rem) / 2)); }

p {
  font-size: 1.5rem;
  line-height: 1.8; }

何も考えずにmargin-bottom: 20px;とやったときの余白の差はこんな感じ。

margin調整について6

View Demo: margin and line-height adjustment

こうやって、きっちり20pxなら20pxの余白になってた方がいいよね!と、この記事の例を見せながらデザイナーのKくんに聞いたら、「そこまでやってくれると嬉しいけど…(;^ω^)」、後輩のMくんに聞いたら、「わ…(;^ω^)」との感想をいただきました。

HTMLとCSSでQRコード

演算処理した結果の何かを出したいと思って思いつきで作ってみた。

Sassで四角形(QRコード)の辺を変えると、その中のパターンも可変するというもの。

HTMLはQRコード(二次元バーコード)作成【無料】でQRコード作って、白黒のパターンに合わせてクラス名を割り振った。29×29パターンあるので、HTMLは割愛。

@charset "utf-8";

//辺の長さを指定
$edge: 145px;

@mixin square {
    height: $edge;
    width: $edge;
}

//29x29パターンに分割したあと、小数点以下切り捨て
@mixin dot {
    height: floor($edge / 29);
    width: floor($edge / 29);
}

.qrcode {
    @include square;
    div {
        overflow: hidden;
    }
}

span {
    @include dot;
    display: block;
    float: left;
}

.b {
    background-color: #000;
}

.w {
    background-color: #FFF;
}

以下出力結果

.qrcode {
  height: 145px;
  width: 145px;
}

.qrcode div {
  overflow: hidden;
}

span {
  height: 5px;
  width: 5px;
  display: block;
  float: left;
}

.b {
  background-color: #000;
}

.w {
  background-color: #FFF;
}

View Demo: QR Code in HTML and CSS

CSS書くよりHTMLでそれぞれ黒か白かを指定するのが面倒くさかった…。メリットは拡大縮小しても滲んだり潰れたりしないことかな。ならSVG使えって話か…。

でもPHPの勉強がてらURL入力してできたQRコード(画像)の白黒部分判別してHTMLとCSSを吐き出すツールを作ってみようかな。うん、そのうちやろう。

参考サイト
QRコード(二次元バーコード)作成【無料】
sassの抑えておきたいfunctionの使い方 « NAVER Engineers’ Blog

CSS3(transition)で円の中心を基準に拡大する丸いボタンをSassで書いてみる

意外とやり方載ってなかったりするよね。で、円の直径を決め打ちすると全部の直径を打ち直さなきゃいけないから、直径を変えたら柔軟に対応してくれるCSSをSassで書いてみた。と言うかSassが書きたかっただけ。でもSassって便利よねー。

HTMLはまんまパクった。

<div id="box">
    <div class="boxin">
        <a href="#" id="circle1">CSS</a>
    </div>
    <div class="boxin">
        <a href="#" id="circle2">CSS3</a>
    </div>
    <div class="boxin">
        <a href="#" id="circle3">jQuery</a>
    </div>
    <div class="boxin">
        <a href="#" id="circle4">Tutorial</a>
    </div>
    <div class="boxin">
        <a href="#" id="circle5">Collect</a>
    </div>
</div>

続いてSass。$circle-diameterの値を変えてやると、円の直径と、基準点が変わる。

@charset "utf-8";

$circle-diameter: 150px; //円の直径
$horizon-margin: 10px;   //円の横マージン
$font-size: 16px;        //フォントサイズ

//円の数によって横幅を変える
@mixin box-width($box-num) {
    width: ($circle-diameter + ($horizon-margin * 2)) * $box-num;
}

@mixin default-circle($value) {
    width: $circle-diameter * $value;
    height: $circle-diameter * $value;
    line-height: $circle-diameter * $value;
}

#box {
    @include box-width(5);
    text-align: center;
    margin: ($circle-diameter / 2) auto;
}

.boxin {
    @include default-circle(1);
    float: left;
    margin: 0 $horizon-margin;
    position: relative;
}

a {
    position: absolute;
    display: block;
    border-radius: 50%;
    text-decoration: none;
    color: #FFF;
    -webkit-transition: 0.5s;
       -moz-transition: 0.5s;
            transition: 0.5s;
    @include default-circle(1);
    font-size: $font-size * 2;
    top: 0;
    left: 0;
    z-index: 10;
    &:hover {
        @include default-circle(2);
        font-size: $font-size * 3;
        top: $circle-diameter - ($circle-diameter * 1.5);
        left: $circle-diameter - ($circle-diameter * 1.5);
        z-index: 100;
    }
}

#circle1 {
    background-color: rgba(73, 10, 61, 0.7);
}

#circle2 {
    background-color: rgba(189, 21, 80, 0.7);
}

#circle3 {
    background-color: rgba(233, 127, 2, 0.7);
}

#circle4 {
    background-color: rgba(214, 174, 0, 0.7);
}

#circle5 {
    background-color: rgba(138, 155, 15, 0.7);
}

View Demo: Relative Center Circle Transition

expandedでの出力結果は以下。

#box {
  width: 850px;
  text-align: center;
  margin: 75px auto;
}

.boxin {
  width: 150px;
  height: 150px;
  line-height: 150px;
  float: left;
  margin: 0 10px;
  position: relative;
}

a {
  position: absolute;
  display: block;
  border-radius: 50%;
  text-decoration: none;
  color: #FFF;
  -webkit-transition: 0.5s;
  -moz-transition: 0.5s;
  transition: 0.5s;
  width: 150px;
  height: 150px;
  line-height: 150px;
  font-size: 32px;
  top: 0;
  left: 0;
  z-index: 10;
}
a:hover {
  width: 300px;
  height: 300px;
  line-height: 300px;
  font-size: 48px;
  top: -75px;
  left: -75px;
  z-index: 100;
}

#circle1 {
  background-color: rgba(73, 10, 61, 0.7);
}

#circle2 {
  background-color: rgba(189, 21, 80, 0.7);
}

#circle3 {
  background-color: rgba(233, 127, 2, 0.7);
}

#circle4 {
  background-color: rgba(214, 174, 0, 0.7);
}

#circle5 {
  background-color: rgba(138, 155, 15, 0.7);
}

やーSass楽しいなぁ。