CSS おれおれ Advent Calendar 2012 – 10日目

iOSの選択ボタン。HTMLでいうラジオボタン的なもの。”Segmented Control”というらしいです。

Segmented Control風ラジオボタン。

HTML

こんな感じです。

<p>
  <span class="segmented">
    <label><input type="radio" name="fruit" value="apple" checked><span class="label">Apple</span></label>
    <label><input type="radio" name="fruit" value="grape"><span class="label">Grape</span></label>
    <label><input type="radio" name="fruit" value="orange"><span class="label">Orange</span></label>
  </span>
</p>

<label />の中に<input type="radio" />と<span />が並んでいます。

ラジオボタンは非表示に

display:noneで隠しておきます。

非表示でも<label />は反応してチェックを切り替えてくれます。

角丸で連結させる

ざっと流れはこんな感じです。

  • 右端以外の枠線を付け、余白ができないように並べる
    • 今回は手っ取り早くfloat
  • 末尾のものだけ右端に枠線を付ける
    • :last-child
  • 先頭、末尾のものだけ角丸にする
    • :first-child
    • border-radius: <top-left> <top-right> <bottom-right> <bottom-left>
.segmented .label {
    /* 右端以外の枠線 */
    border: 1px #ccc;
    border-style: solid none solid solid;

    /* 隙間を詰める */
    float: left;

    /* 背景グラデーション */
    background-color: #eee;
    background-image: linear-gradient(to bottom, hsl(0,0%,98%) 0%,hsl(0,0%,77%) 100%);

    /* ラベルテキスト */
    color: #777;
    text-align: center;
    text-shadow: 1px 1px #fff;

    cursor: pointer;
    padding: 8px;
    width: 80px;
}
/* 先頭のもの */
.segmented :first-child .label {
    /* 左上、左下の角を丸める */
    border-radius: 10px 0 0 10px;
}
/* 末尾のもの */
.segmented :last-child .label {
    /* 右端の枠線 */
    border-right-style: solid;

    /* 右上、右下の角を丸める */
    border-radius: 0 10px 10px 0;
}

先日書いたので、詳細はこちらを。

縦に並んでいたものを横に並べれば目的のスタイルになります。

背景色をグラデーション

CSS3のlinear-gradient()を使います。

グラデーションはまだベンダープレフィックスが必要です。(見づらいので、ここだけ分けて書いてみました。)

.segmented .label {
    background-image: -moz-linear-gradient(top, hsl(0,0%,98%) 0%,hsl(0,0%,77%) 100%);
    background-image: -ms-linear-gradient(top, hsl(0,0%,98%) 0%,hsl(0,0%,77%) 100%);
    background-image: -webkit-linear-gradient(top, hsl(0,0%,98%) 0%,hsl(0,0%,77%) 100%);
    background-image: linear-gradient(to bottom, hsl(0,0%,98%) 0%,hsl(0,0%,77%) 100%);
}

いやー、ベンダープレフィックス邪魔ですねえ。

(ここの色を調節したらもっと近づくんじゃないかと思うのですが、私では無理でした……。)

チェックが付いたらスタイル変更

さてここが今回のキモ。JavaScriptで切り替えても良いのですが、CSSだけで済ましてしまいましょう。

直接隣接結合子+を使います。<input />と<span />を並べたのはこのためです。

チェックされているラジオボタン:selectedの直後に出現+する要素spanのスタイルを変えます。

つまり、こんなセレクターになります。

  • :checked + span

これを使って、今回のものを組みましょう。変えるのは文字色と背景色ですね。

.segmented input:checked + .label {
    /* 文字色を変える */
    color: #fff;
    text-shadow: -1px -1px rgba(0,0,0,.3);

    /* 背景色を変える */
    background-color: #00f;
    background-image: linear-gradient(to bottom, hsl(214,90%,40%) 0%, hsl(214,90%,70%) 100%);    
    border-color: hsl(214, 90%, 60%);
    box-shadow: 3px 2px 10px rgba(0,0,0,.2) inset, -3px 2px 10px rgba(0,0,0,.2) inset;
}

できた!

こんなん出ました。

ね、簡単でしょう?