CSSの角丸(border-radius)を作る
コード
そのまま貼れる形です。同じ数が続くところは、書かなければ他の角から写されるので、ここまで短くできます。
border-radius: 16px;
省略しないで書くと、こうなります。上のプレビューはこの文字列で描いています。何番目がどの角かを数えたいときはこちらです。
border-radius: 16px 16px 16px 16px;
1つずつのプロパティに分けると、スラッシュの正体が見えます。1つの角が2つの長さを持っているだけでした。
border-top-left-radius: 16px; border-top-right-radius: 16px; border-bottom-right-radius: 16px; border-bottom-left-radius: 16px;
長い行は、この枠の中だけ横に動かせます(キーボードでも動きます)。
よくある質問
border-radiusの4つの値は、どの角から始まりますか?
左上から時計回りで、左上・右上・右下・左下の順です。marginやpaddingの4つの値が上・右・下・左であるのと、始まる場所が違います。あちらは辺を数え、こちらは角を数えるからです。どちらも時計回りなので、順番を覚えていても1つめが指すものを取り違えます。値を減らしたときの埋め方は同じで、3つなら左下が右上と同じに、2つなら右下が左上と、左下が右上と同じになります。
border-radiusのスラッシュは何ですか?
スラッシュの前がよこ方向の半径、うしろがたて方向の半径です。1つの角は2つの長さを持っていて、その2つが違うと角の曲線は円の一部ではなく楕円の一部になります。だからborder-radiusは4つではなく8つの値を取れます。1つずつのプロパティで書けば、border-top-left-radius: 60% 40%; のように2つの長さが並んでいるのが見えます。
border-radius: 50% にすると必ず円になりますか?
箱が正方形のときだけです。パーセントは、よこ半径が幅に対する割合、たて半径が高さに対する割合として計算されます。240×160の箱に50%を書くと、よこ半径120・たて半径80になり、円ではなく楕円になります。円にしたいときは、幅と高さを同じ数にしてください。仕様にも15em×10emの箱を楕円にする例が載っています。
辺より大きい半径を書くとどうなりますか?
ブラウザが自動で縮めます。仕様は、上下左右それぞれについて「辺の長さ÷その辺の両端の半径の合計」を求め、いちばん小さい値をfとして、fが1より小さければ4つの角すべてにfを掛ける、と定めています。溢れていない辺の角まで同じ倍率で縮む点に注意してください。border-radius: 9999px と書いてカプセル形になるのは、この決まりのおかげです。
border-radiusにマイナスの値は書けますか?
書けません。仕様に「Negative values are invalid」と明記されています。角を内側にえぐりたいときは、border-radiusではできません。0を書くと、その角は丸くならず四角のままになります。仕様の言い方では「どちらかの長さが0なら、その角は四角で、丸くない」です。
角を丸めた部分は、クリックできなくなりますか?
できなくなります。仕様は、背景や、はみ出した中身や、ポインタのイベントを、それぞれ対応する角の曲線で切り取ると定めています。つまり削れた角の外側は当たり判定から外れます。仕様はさらに、border-radiusは要素の操作できる面積を減らすので、残った面積が推奨される最小のタップ領域を満たすか確かめるべきだ、と注意しています。丸くしたぶん、ボタンは少し大きめに作るのが安全です。
表に角丸が効かないことがあるのはなぜですか?
border-collapse: collapse のときは効かないと仕様が定めているからです。border-radiusが効くのは、table・inline-table・table-cellのうち、罫線を離して描くモード(border-collapse: separate)のときだけです。罫線を重ねて1本にするモードでは、隣り合うセルの罫線が共有されるので、角ごとに別の曲線を描けなくなります。
つまみを動かすと、そのまま貼れるCSSが出ます。border-radiusは4つではなく8つの値を取れるので、 角を円ではなく楕円にできます。葉っぱやしずくの形も、これで作ります。
4つの値は「左上から時計回り」です
ここが最初につまずくところです。marginやpaddingの4つの値は「上・右・下・左」ですが、border-radiusは「左上・右上・右下・左下」。 どちらも時計回りなのに、1つめが指すものが違います。
理由は単純で、marginは「辺」を数え、border-radiusは「角」を数えているからです。 辺は上から、角は左上から始まります。 だから「時計回り」だけを覚えていると、必ず取り違えます。
| 何番目 | border-radius(角) | margin・padding(辺) |
|---|---|---|
| 1つめ | 左上 | 上 |
| 2つめ | 右上 | 右 |
| 3つめ | 右下 | 下 |
| 4つめ | 左下 | 左 |
値を4つ書かなかったときの埋め方も、決まっています。右上を書かなければ左上と同じ、右下を書かなければ左上と同じ、左下を書かなければ右上と同じ。 だからborder-radius: 8pxと1つ書けば4つの角が8pxになり、border-radius: 8px 24pxと2つ書けば斜め向かいどうしが同じになります。
スラッシュの前がよこ、うしろがたて。だから角が楕円になります
1つの角は、2つの長さを持っています。よこ方向にどれだけ、たて方向にどれだけ削るか。 この2つが同じなら角は円の一部になり、違うなら楕円の一部になります。
4つの値しか書かないときは、たての値がよこの値からそのまま写されているだけです。スラッシュを書くと、その写しをやめて別々に指定できます。 前に4つ、うしろに4つ ── これで8つの値になります。
仕様には2em 1em 4em / 0.5em 3emという例が載っていて、展開したあとの4行まで書かれています。 この道具が使っているのと同じ計算で開くと、 こうなります。
| 角 | よこ半径 | たて半径 |
|---|---|---|
| 左上 | 2em | 0.5em |
| 右上 | 1em | 3em |
| 右下 | 4em | 0.5em |
| 左下 | 1em | 3em |
表が入りきらないときは、表の上で横に動かせます(キーボードでも動きます)。
よく見ると、左下の値がどこにも書かれていないのに 1em と 3em が入っています。 書かれた3つは左上・右上・右下ぶんで、左下は右上から写されたからです。 スラッシュのうしろも同じで、2つしか書かれていないので斜め向かいどうしで写し合っています。
50%で円になります。ただし正方形のときだけです
4つの角すべてを50%にすると、まっすぐな辺が1本も残りません。角の曲線どうしが直接つながるので、四角形ではなく丸い形になります。
ここで大事なのが、パーセントが何に対する割合かです。 仕様は「よこ半径のパーセントは幅、たて半径のパーセントは高さ」と決めています。 だから240×160の箱に50%と書くと、よこ半径120・たて半径80という違う長さになり、出てくるのは円ではなく楕円です。
まん丸にしたいなら、幅と高さを同じ数にする── これが「50%で円」の本当の中身です。 上の見本で「円」と「楕円」を続けて押すと、指定は同じ50%のまま、箱の形だけが違うことが分かります。
半径の合計が辺より長いと、ブラウザが勝手に縮めます
大きい数を書いても、はみ出したり重なったりはしません。ブラウザが自動で全部を縮めます。これは実装のくせではなく、仕様に式が書いてある決まりです。
4つの辺それぞれについて「辺の長さ ÷ その辺の両端にある半径の合計」を求め、 いちばん小さい値を f とします。 f が1より小さければ、4つの角すべてに f を掛けます。
仕様に載っている例で確かめてみます。幅6em・高さ2emの箱にborder-radius: 0.5em 2em 0.5em 2em。 上下の辺は 6 ÷ 2.5 = 2.4 で余裕がありますが、 左右の辺は 2 ÷ 2.5 = 0.8 で足りません。 だからf は0.8になり、 0.5em は 0.4em に、2em は 1.6em に縮みます。仕様に書かれている答えと同じです。
ここで見落としやすいのが、溢れていない辺の角まで、同じ倍率で縮むところです。 上下の辺は余っていたのに、上下ぶんの半径も0.8倍になりました。「4つの角すべてに」と書いてあるからです。
この決まりのおかげで、カプセル形は雑に作れます。border-radius: 9999pxのように大きすぎる数を書けば、 ブラウザがちょうど半分で止めてくれるからです。 上の見本の「カプセル」は、 200pxと書いて0.4倍に縮められた結果です。
丸めた角は、押せなくなります
見た目の話で終わらないところがあります。 仕様は、背景も、はみ出した中身も、ポインタのイベントも、角の曲線で切り取ると定めています。 つまり削れた角の外側は、クリックにもタップにも反応しません。
仕様自身がそこに注意書きを付けていて、「border-radiusは要素の操作できる面積を減らすので、 残った面積が推奨される最小のタップ領域を満たすか確かめること」と書いています。 丸くするほど、四隅の押せない部分が増えていくわけです。
このサイトのボタンを44ピクセル以上にしているのも同じ理由からです。 角丸をきつくしたボタンは、見た目の大きさより実際に押せる面積が小さいことを覚えておくと、小さくて押しにくいボタンを作らずにすみます。
決まりの出どころは、値の順番・スラッシュ・パーセント・マイナス・縮める式・ 当たり判定のすべてがW3C の CSS Backgrounds and Borders Module Level 3(4. Rounded Corners)(新しいタブで開きます)、 marginの4つの値の順番がCSS Box Model Module Level 3(新しいタブで開きます)です。 このページに出てくる数と展開結果は、どれも仕様に載っている例をこの道具の計算で解き直したもので、 答えが仕様の記述と一致することを単体テストで毎回確かめています。