HTMLとCSSだけで簡単に作る。軽量な開く・閉じる切り替えボタン

  • ---

    LINEで送る
  • -

    ブックマーク
  • -

    pocket
  • -

    rss
html5 css3 image
イラストACの画像をもとに加工しています。

HTMLとCSSだけで『開く・閉じる』の切り替えボタンをかんたんに作る方法をご紹介します。

画面を遷移しないでコンテンツを開閉します。JavaScriptは使いません。

これは、コンテンツをコントロールするときWebサーバーにリクエストを送信しないので、Webページのパフォーマンスを上げることができます。

『Run Pen』を押すと、今回のソースコードサンプルが表示されます。これを、HTMLとCSSだけでつくります。

少しづつ実装するので、とてもかんたんで分かりやすいと思います。

JavaScriptを使わずにコンテンツを『開く・閉じる』

サンプルをつくっていく前に、JavaScriptを使わないメリットを説明します。

-> 説明はいらない人はジャンプ

HTMLとCSSだけでボタンを作成するメリットは、Webサーバにリクエストする回数を最小限にすることです。

そのしくみは、

  • ブラウザからhttpリクエストを送信。
  • Webサーバーから、コンテンツが開いた状態のHTMLを返す
  • CSSでコンテンツの初期表示を設定(初期状態は『開く』『閉じる』のどちらでもよい)
  • コンテンツを開いたり閉じたりする切り替えをCSSで行う。

です。これは、コンテンツの表示・非表示の切り替えで画面を遷移しません。

また、JavaScriptを使わないのでブラウザの負荷を軽くすることができます。結果的にWebページのパフォーマンスが向上します。

切り替えボタンの動作をCSSのみで行なうかんたんな作り方

少しだけHTMLも関係していますが、コンテンツの『開く・閉じる』の動作はほぼすべてCSSだけで行ないます。

CSSの記述はかんたんです。ソースコードのサンプルを少しづつ実装しながら見ていきましょう。

ソースコードサンプルのボックスにタップやマウスを合わせると、右上にコピーボタンが出ます。

慣れないうちは、とりあえずコピー&ペーストで、自分で動かすところから始めると良いです。

開く・閉じるボタン切り替えのソースコードサンプル

まずは次のHTML&CSSを見てください。

HTML
<input type="radio" class="radio" id="open" name="btn" /><label class="btn btn-open" for="open">開く</label>
<input type="radio" class="radio" id="close" name="btn" checked="checked" /><label class="btn btn-close" for="close">閉じる</label>
<div class="box">制御されるコンテンツ</div>
CSS
.btn {
    color: #fff;
    background: rgba(127, 194, 239, .5);
    padding: .3em .5em;
    margin-bottom: .3em;
    border-radius: .3em;
    text-align: center;
    display: table; 
}
.btn:hover {
    cursor: pointer;    
}
.btn:active {
    background: rgb(127, 194, 239);
}
.box {
    border: 2px solid #d685b0;
    border-radius: .3em;
    height: 200px;
}

HTMLはラジオボタンとそのラベルの2つずつでボタンを作って、コントロールされるエリアを用意しただけです。

ボタンには、まだボタンとしての機能はありません。

CSSは、ボタンっぽい見た目と押したときのスタイルを入れました。そしてコンテンツが見えやすいように枠をつけました。

まずはこの状態で動かしてみましょう。

HTML結果
制御されるコンテンツ

ボタンを切り替えるはずが、2つとも表示されています。そして見えてほしくないラジオボタンが見えてしまっています。

また、ボタンを押してもラジオボタンが切り替わるだけで、エリアには何も起きません。

このままでは何の意味もありません。ここでCSSに、ボタンをコントロールする処理を追加します。

まずはHTMLを変更します。

変更したHTML
<div class="add-control">
  <!-- さっきのHTML -->
</div>
<div class="add-control">
  <input type="radio" class="radio" id="open" name="btn" /><label class="btn btn-open" for="open">開く</label>
  <input type="radio" class="radio" id="close" name="btn" checked="checked" /> 
  <label class="btn btn-close" for="close">閉じる</label>
  <div class="box">制御されるコンテンツ</div>
</div>

ボタンのコントロール用クラスを親要素のdivに追加しただけです。

次に、CSSにadd-controlクラスについてコードを追加します。

/* radio non-display */
.add-control .radio{
    display: none;
}
/* button control */
.add-control #close:checked ~ .btn-close {
    display: none;
}
.add-control #close:checked ~ .btn-open {
    display: table;
}
.add-control #open:checked ~ .btn-close {
    display: table;
}
.add-control #open:checked ~ .btn-open {
    display: none;
}
/* content control */
.add-control #close:checked ~ .box {
    display: none;
}
.add-control #open:checked ~ .box {
    display: block;
}
CSSセレクタ(~: 同じ階層を見る)

要素と同じ階層にある要素に対してスタイルを適用させるためのセレクタ。間接セレクタ。兄弟(姉妹)セレクタとも言う。

<div class="parent">親
  <div class="child-1">子</div>
  <div class="child-2">子</div>
  <div class="child-3">子
    <div class="child-child">孫</div>
  </div>
</div>

CSSサンプル

// child-1, child-2, child-3が対象
.child-1 ~ div {
  color: red;
}

処理の内容

  • ラジオボタンはいらないのでかくす。
  • 閉じるボタンが押された → 閉じるボタンかくす・開くボタン表示。エリアかくす。
  • 開くボタンが押された → 開くボタンかくす・閉じるボタン表示。エリア表示。

くわしい説明はあとのほうでします。

まずは動かしてみましょう。

-> 動かさなくていい。説明を見る。

HTML結果
制御されるコンテンツ

HTMLとCSSだけで開く・閉じるボタンができました。

これまで順を追ってサンプルコードを作ってきました。それを整理すると最初にみたCodePenのHTML&CSSになります。

初期状態を『閉じるボタン+コンテンツ表示』に変えるのはかんたんです。htmlのラジオボタンで、閉じるボタンからchecked属性をはずして開くボタンにつけるだけです。

HTMLの結果だけを表示します。

初期表示の変更 - 最初は開く -
制御されるコンテンツ

【解説】CSSのボタン切り替えのポイント(:checked 疑似クラス)

『開く・閉じる』ボタンの切り替え、コンテンツの表示・非表示には、CSSの:checked疑似クラスを使う

:checked疑似クラスは、HTMLのinput要素のchecked属性と連動しています。

HTMLのchecked属性は、input要素のチェックボタンやラジオボタンなどで選択されると、checked属性がつけられます。

サンプルコードでは、閉じるボタンのinput要素に初期値としてchecked属性がついるので、閉じるボタンはかくれ、開くボタンを表示します。

checked属性のついたラジオボタン
<input type="radio" class="radio" id="close" name="btn" checked="checked" />

【解説】HTML文のボタン切り替えのポイント(radioボタンを使用)

HTMLは、radioボタンをカスタマイズして開く・閉じるボタンに使う

ラジオボタンは、複数のボタンで選ぶことができるのがひとつだけで、『開く』『閉じる』の一方を選択するのと動きが同じです。

これがラジオボタンを使う理由です。

ラジオボタンをクリックすると、input要素のchecked属性が自動的に切り替わるので、これを開く・閉じるボタンの切り替え、エリアの表示・非表示に使います。

ラジオボタンは内部の切り替え機能だけが必要なので、CSSのdisplay:noneでかくします。

ボタンの表示はラジオボタンのとなりにあるテキスト部分(label要素)で表現します。

【解説】CSSのボタン切り替え

ボタンの切り替えはCSSで行う

ラジオボタンのchecked属性(HTML)だけでボタンを切り替えるので、JavaScriptはいりません。

HTML&CSSだけでボタンが切り替えられるのは、HTMLにある機能だけでコントロールするからです。

CSSはそれを見た目の面でカバーしているだけです。

CSSでのボタンの切り替えの記述は、さっき見たように20行もありません。(checked疑似クラスがついたところ)

  • checked属性がついたボタンはかくして、もう一方のボタンを表示。
  • 閉じるボタンにchecked属性がついて、連動してコンテンツをかくす。(display: noneを使う)
  • 開くボタンにchecked属性がついて、連動してコンテンツを表示。(display:tableで表示)(tableを使うと文字列の長さにボタン幅が自動調整される。inline-blockと同じ。)

ボタンの処理でやっていることはこれだけです。

もうひとつの方法

これまで見てきたサンプルよりも、もっと短いコードでかんたんな方法があります。

ラジオボタンをチェックボックスにする方法です。ボタンの数がひとつなので、その分だけCSSのボタンのコントロールが少なくなります。

20行が10行くらいまで少なくできます。

こっちを先にいってくれよ!

と思うでしょうが、チェックボックスは機能の拡張がむずかしいです。

(例えば『ボタンを3個以上に増やす』とか。)

サンプルで見た方法は、ラジオボタンを増やすだけでできます。

チェックボックスは、ボタンがふたつに限定されるオン/オフ機能で使えます。サンプルの『閉じる・開く』もそのひとつです。

処理の内容はほとんど一緒です。

HTMLとCSSの完成したサンプルコードからHTML結果まで一気に見ていきます。

HTML
<div class="add-control">
  <input type="checkbox" class="chk" id="open-close" name="btn" /><label class="btn btn-open-close" for="open-close"></label>
  <div class="box">制御されるコンテンツ</div>
</div>
CSS
.btn {
    color: #fff;
    background: rgba(127, 194, 239, .5);
    padding: .3em .5em;
    margin-bottom: .3em;
    border-radius: .3em;
    text-align: center;
    display: table; 
}
.btn:hover {
    cursor: pointer;    
}
.btn:active {
    background: rgb(127, 194, 239);
}
.box {
    border: 2px solid #d685b0;
    border-radius: .3em;
    height: 200px;
}

/* checkbox non-display */
.add-control .chk{
    display: none;
}
/* button control */
.add-control #open-close ~ .btn-open-close::before {
    content: "開く" ;
}
.add-control #open-close ~ .box {
    display: none ;
}
.add-control #open-close:checked ~ .btn-open-close::before {
    content: "閉じる" ;
}
.add-control #open-close:checked ~ .box {
    display: block ;
}
CSS
.btn {
    color: #fff;
    background: rgba(127, 194, 239, .5);
    padding: .3em .5em;
    margin-bottom: .3em;
    border-radius: .3em;
    text-align: center;
    display: table; 
}
.btn:hover {
    cursor: pointer;    
}
.btn:active {
    background: rgb(127, 194, 239);
}
.box {
    border: 2px solid #d685b0;
    border-radius: .3em;
    height: 200px;
}

/* checkbox non-display */
.add-control .chk{
    display: none;
}
/* button control */
.add-control #open-close ~ .btn-open-close::before {
    content: "開く" ;
}
.add-control #open-close ~ .box {
    display: none ;
}
.add-control #open-close:checked ~ .btn-open-close::before {
    content: "閉じる" ;
}
.add-control #open-close:checked ~ .box {
    display: block ;
}
checkbox版
制御されるコンテンツ

さらにかんたんにできましたね?

チェックボックス版のポイントは、ラベルをHTMLに書かずに、CSSの::before疑似クラスで書いていることです。

あとは、CSSでエリアを切り替えるとき一緒にボタン名を切り替えるだけです。

  • HTMLのラベルは空で作る。
  • ボタン名はCSSの::before疑似クラス+contentプロパティで作る。
  • CSSのボタン切り替えで、エリアのON/OFF, ボタン名を切り替える。

ちなみに、::before疑似クラスではなく、HTMLにボタンをふたつ用意して"display:none"で制御することもできます。

ボタンをHTMLに書く
HTML
<div class="add-control">
<input type="checkbox" class="chk" id="open-close" name="btn"><label class="btn btn-open-close" for="open-close"><span class="open">開く</span><span class="close">閉じる</span></label>
<div class="box">制御されるコンテンツ</div>
</div>
CSS
.btn {
    color: #fff;
    background: rgba(127, 194, 239, .5);
    padding: .3em .5em;
    margin-bottom: .3em;
    border-radius: .3em;
    text-align: center;
    display: table; 
}
.btn:hover {
    cursor: pointer;    
}
.btn:active {
    background: rgb(127, 194, 239);
}
.box {
    border: 2px solid #d685b0;
    border-radius: .3em;
    height: 200px;
}

/* checkbox non-display */
.add-control .chk{
    display: none;
}
/* button control */
.add-control #open-close ~ .box {
    display: none ;
}
.add-control #open-close ~ .btn-open-close .open {
    display: inline;
}
.add-control #open-close ~ .btn-open-close .close {
    display: none;
}
.add-control #open-close:checked ~ .btn-open-close .open {
    display: none;
}
.add-control #open-close:checked ~ .btn-open-close .close {
    display: inline;
}
.add-control #open-close:checked ~ .box {
    display: block ;
}

まとめ

  • HTMLはradioボタンのchecked属性を使う
  • CSSは:checked疑似クラスを使う

HTMLとCSSだけでコントロールする開く・閉じるボタンは、見た目と動きでむずかしく感じますが、じっさいはかんたんですね?

サンプルコードではデザインをシンプルにしています。もっとオシャレにしたいときは、ラベルとコンテンツエリアのborder, color, backgroundあたりを変えれば劇的に変わります。

:checked疑似クラスはCSS3から実装された機能です。現在のブラウザは対応しているので気にすることはないですが、どうしても動かない場合の知識として押さえておきましょう。

今回ご紹介した開く・閉じるボタンとまったく同じ作り方で、JavaScriptを使わないその他の機能も実装できます。

HTML&CSSの本
post-cta-image

どうしてもインターネットで調べて勉強するのが苦手という人のために、HTMLとCSSの最新技術と基本を網羅できる本を2冊選びました。

この内容を身につければ、ほかの本は必要ありません。将来的には、自分の力で、書籍を使わずに、インターネットにある情報だけで学べます。


HTML&CSSの本2選

SNSでも記事を配信しています。
コメントを残す

*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

top
この記事を気に入ったらぜひシェアも!!