HTMLとCSSだけで『閉じる・すべて表示』ボタンをかんたんに作る方法をご紹介します。
このボタンは、画面を遷移しないでコンテンツを閉じたり追加表示します。JavaScriptは使いません。
これは、コンテンツを制御するときに、Webサーバーにリクエストを送信しないので、Webページのパフォーマンスを上げることができます。
まず完成したサンプルから。
See the Pen sample buttom - close and display-all by tadtadya (@tadtadya) on CodePen.
これをHTMLとCSSだけでつくります。少しづつ実装するので、とてもかんたんで分かりやすいと思います。
JavaScriptを使わずにコンテンツを『閉じる・すべて表示』
サンプルをつくっていく前に、JavaScriptを使わないメリットから。
TMLとCSSだけでボタンをつくるとWebサーバにリクエストする回数を最小限にできます。そのしくみは、
- ブラウザからhttpリクエストを送信する。
- Webサーバーから、コンテンツが開いた状態のHTMLを返す。
- ページを最初に表示するときは、CSSでコンテンツを閉じた状態にする。
- コンテンツを閉じたり追加表示する動作をCSSで制御する。
これはコンテンツの非表示 -> 表示の切り替えでページ遷移をしません。
また、コンテンツをリクエストで再取得しないとしても、JavaScriptのDOM操作がいらないので、その分だけブラウザの負荷を軽くできます。
あらかじめ、CSSですべての操作のスタイルが定義されているので、CSSOMの再展開がない。
(CSSOMはCSSのDOMみたいなもの。)
(JavaScriptのDOM, CSSOM操作の分がいらない。)
また、HTML, CSSに任せることでJavaScriptのコードを少なくできる。
ボタンの動作をCSSだけで行なう簡単な作り方
少しだけHTMLも関係しますが、コンテンツの『閉じる・すべて表示』のほぼすべてはCSSだけで行ないます。
CSSの記述はかんたんです。ソースコードのサンプルを少しづつ実装しながら見ていきましょう。
ソースコードサンプルのボックスにタップやマウスを合わせると、右上にコピーボタンが出ます。
慣れないうちは、とりあえずコピー&ペーストで、自分で動かすところから始めると良いです。
閉じるボタンのソースコードサンプル
まずは、閉じるボタンから作ります。
<div class="action-close">
<input id="close" class="checkbox" name="close" type="checkbox"><label class="btn" for="close">閉じる</label>
<div class="box">閉じることができるコンテンツ</div>
</div>
.btn {
color: #fff;
background: rgba(127, 194, 239, .5);
padding: .3em .5em;
border-radius: .3em;
text-align: center;
display: table;
cursor: pinter;
}
.btn:hover {
cursor: pinter;
}
.btn:active {
background: rgb(127, 194, 239);
}
.box {
border: 2px solid #d685b0;
border-radius: .3em;
height: 200px;
}
/* close button */
.action-close {
position: relative;
margin-top: 2em;
}
.action-close .btn {
position: absolute;
right: 0;
top: -1em;
}
.action-close .box {
margin-bottom: 2em;
border: 2px solid rgb(127, 194, 239);
}
HTMLはチェックボックスとラベル、閉じられるエリアだけです。閉じるボタンは、チェックボックスとラベルで作りました。ボタンにはまだボタン機能はありません。
CSSは、チェックボックスのラベルにボタンっぽい見た目と、ボタンを押したときのスタイルを入れました。そのほかは細かい見た目の調整です。
HTMLの結果です。
ボタンを押してもチェックボックスが変化するだけでコンテンツはかくれません。そして、見えてはいけないチェックボックスが見えています。
このままでは何の意味もありません。そこで、CSSにボタンの処理を追加します。
まずは、HTMLを変更します。
<div class="add-control">
<!-- さっきのHHTML -->
</div>
ボタンのコントロール用クラスを親要素のdivに追加しました。そのほかに変更はありません。
コードの全文はこうなります。
<div class="add-control">
<div class="action-close">
<input type="checkbox" class="checkbox" id="close" name="close" /><label for="close" class="btn">閉じる</label>
<div class="box">閉じることができるコンテンツ</div>
</div>
</div>
次にCSSにadd-controlクラスのコードを追加します。
/* checkbox non-display */
.add-control .checkbox {
display: none;
}
/* close button's control */
.add-control .action-close #close:checked ~ .btn {
display: none;
}
.add-control .action-close #close:checked ~ .box {
display: none;
}
チェックボックスとラベルをボタンに変身させる処理はこれだけです。
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;
}
CSSのボタンコントロールの処理
- チェックボタンを非表示。
- 閉じるボタンが押された -> 閉じるボタン非表示
- 閉じるボタンが押された -> コンテンツボックス非表示
.btn {
color: #fff;
background: rgba(127, 194, 239, .5);
padding: .3em .5em;
border-radius: .3em;
text-align: center;
display: table;
cursor: pinter;
}
.btn:hover {
cursor: pinter;
}
.btn:active {
background: rgb(127, 194, 239);
}
.box {
border: 2px solid #d685b0;
border-radius: .3em;
height: 200px;
}
/* close button */
.action-close {
position: relative;
margin-top: 2em;
}
.action-close .btn {
position: absolute;
right: 0;
top: -1em;
}
.action-close .box {
margin-bottom: 2em;
border: 2px solid rgb(127, 194, 239);
}
/* checkbox non-display */
.add-control .checkbox {
display: none;
}
/* close button's control */
.add-control .action-close #close:checked ~ .btn {
display: none;
}
.add-control .action-close #close:checked ~ .box {
display: none;
}
さっそく動かしてみましょう。
HTMLの結果です。
CSSでボタンの動きができました。
次は『すべて表示』ボタンのサンプルコードです。やることは一緒で、表示/非表示のデフォルトが逆になるだけです。
もう分かったから解説が見たい
『すべて表示』ボタンのサンプルも見たい
すべて表示ボタンのソースコードサンプル
すべて表示ボタンのHTMLです。量が少ないので全文表示します。
<div class="add-control">
<div class="action-allopen">
<p>ここに序文があります。</p>
<input type="checkbox" class="checkbox" id="allopen" name="allopen" /><label for="allopen" class="btn">すべてを表示</label>
<div class="box">
<p>追加された本文です</p>
<p>追加された本文です</p>
<p>本文の終わりです。</p>
</div>
</div>
</div>
- 親のdivクラス(.action-allopen)
- チェックボックスとラベル
- ボタンでコントロールされるエリア(.box)
ほとんど閉じるボタンと一緒ですね? 違いはクラス名をそれらしくなおしているのと、コメントが追加されてるくらいです。
CSSもほとんど一緒ですが、とりあえずボタン機能がない状態からいきます。
.btn {
color: #fff;
background: rgba(127, 194, 239, .5);
padding: .3em .5em;
border-radius: .3em;
text-align: center;
display: table;
cursor: pinter;
}
.btn:hover {
cursor: pinter;
}
.btn:active {
background: rgb(127, 194, 239);
}
.box {
border: 2px solid #d685b0;
border-radius: .3em;
height: 200px;
}
/* close button */
.action-close {
position: relative;
margin-top: 2em;
}
.action-close .btn {
position: absolute;
right: 0;
top: -1em;
}
.action-close .box {
margin-bottom: 2em;
border: 2px solid rgb(127, 194, 239);
}
/* all-display */
.action-allopen .btn {
margin: 0 auto;
}
.action-allopen .box {
border: none;
height: auto;
}
ボタンとコントロールされるエリアの見た目の部分を、さっきのCSSからもってきます。
そしてちょっと追加します。これもボタンとエリアの見た目の調整です。もちろんボタンの機能はありません。
/* all-display */
.action-allopen .btn {
margin: 0 auto;
}
.action-allopen .box {
border: none;
height: auto;
}
一応ボタン機能のないHTMLを動かしてみます。
ここに序文があります。
追加された本文です
追加された本文です
本文の終わりです。
閉じるボタンと同じです。チェックボックスが見えてしまっているのと、ボタンを押してもチェックボックスが変わるだけです。
これにさっきと同じようにCSSにボタン機能を追加します。
/* checkbox non-display */
.add-control .checkbox {
display: none;
}
/* all-display's control */
.add-control .action-allopen .box {
display: none;
}
.add-control .action-allopen #allopen:checked ~ .btn {
display: none;
}
.add-control .action-allopen #allopen:checked ~ .box {
display: block;
}
これもさっきとほぼ同じです。
- チェックボタンを非表示。
- .boxの最初の状態は非表示。
- ボタンが押された -> ボタン非表示
- ボタンが押された -> コンテンツボックス表示
HTMLを実行します。
ここに序文があります。
追加された本文です
追加された本文です
本文の終わりです。
すべて表示ボタンができました。
<div class="add-control">
<div class="action-allopen">
<p>ここに序文があります。</p>
<input type="checkbox" class="checkbox" id="allopen" name="allopen" /><label for="allopen" class="btn">すべてを表示</label>
<div class="box">
<p>追加された本文です</p>
<p>追加された本文です</p>
<p>本文の終わりです。</p>
</div>
</div>
</div>
.btn {
color: #fff;
background: rgba(127, 194, 239, .5);
padding: .3em .5em;
border-radius: .3em;
text-align: center;
display: table;
cursor: pinter;
}
.btn:hover {
cursor: pinter;
}
.btn:active {
background: rgb(127, 194, 239);
}
.box {
border: 2px solid #d685b0;
border-radius: .3em;
height: 200px;
}
/* close button */
.action-close {
position: relative;
margin-top: 2em;
}
.action-close .btn {
position: absolute;
right: 0;
top: -1em;
}
.action-close .box {
margin-bottom: 2em;
border: 2px solid rgb(127, 194, 239);
}
/* all-display */
.action-allopen .btn {
margin: 0 auto;
}
.action-allopen .box {
border: none;
height: auto;
}
/* checkbox non-display */
.add-control .checkbox {
display: none;
}
/* all-display's control */
.add-control .action-allopen .box {
display: none;
}
.add-control .action-allopen #allopen:checked ~ .btn {
display: none;
}
.add-control .action-allopen #allopen:checked ~ .box {
display: block;
}
【解説】CSSのボタン処理のポイント(:checked 疑似クラス)
閉じる・すべてを表示ボタンの処理、コンテンツの表示・非表示には、CSSの:checked疑似クラスを使う
:checked疑似クラスは、HTMLのinput要素のchecked属性と連動しています。
HTMLのchecked属性は、input要素のチェックボタンやラジオボタンなどで選択されると、checked属性がつけられます。
【解説】HTML文のボタン処理のポイント(チェックボックスを使用)
HTMLは、チェックボックスをカスタマイズしてボタンに使う
チェックボックスを使う理由は、checked属性が使えるのと、on/offの機能が一度押したら消えるボタンで流用しやすいからです。
チェックボックスでチェックをつけるとinput要素にchecked属性がつけられるので、ボタンの処理でコンテンツの表示/非表示に使います。
チェックボックスは内部の機能だけが必要なので、CSSのdisplay:noneでかくします。
そしてボタンの表示は、チェックボックスのとなりにあるテキスト部分(label)で表現します。
【解説】CSSのボタン処理
ボタン処理のコントロールはCSSで行う
HTMLのチェックボックスのchecked属性だけでボタン処理を行うので、JavaScriptはいらないです。
HTML&CSSだけでボタン処理ができるのは、そのコントロールをHTMLにある機能だけで行うからです。
CSSは見た目の面でカバーしているだけです。
CSSのボタン処理の部分はサンプルコードで見たように10行くらいです。
- checked属性がついたボタンはかくす。
- ボタンにchecked属性がついて、連動してコンテンツをかくすときはdisplay: noneを使う
- ボタンにchecked属性がついて、連動してコンテンツを表示するときはdisplay:blockを使う
ボタンの処理でやっていることはこれだけです。
まとめ
- HTMLはチェックボックスのchecked属性を使う
- CSSは:checked疑似クラスを使う
HTMLとCSSだけで閉じる・すべてを表示ボタンは、見た目と動きでむずかしく感じますが、じっさいはかんたんですね?
サンプルコードではデザインをシンプルにしています。もっとオシャレにしたい場合は、ラベルとコンテンツエリアのborder, color, backgroundあたりを変えれば劇的に変わります。
:checked疑似クラスはCSS3から実装されました。現在のブラウザは対応しているので気にすることはないですが、どうしても動かない場合の知識として押さえておきましょう。
今回ご紹介した閉じる・すべて表示ボタンと同じ作り方で、JavaScriptを使わないほかの機能も実装できます。