コピペでOK! CSSだけでWebページに開閉ボタンを設置して記事の一部を表示非表示する

Web記事を書くとき、キーワードによっては次のような事態に直面することがあります。

・一部の読者は、詳しい情報を欲している。
・その他の読者は、簡潔な情報のみでよい。

このケースで詳しい情報を記事に掲載すると、その他の読者が離脱する可能性があります。

それでも詳しい情報を掲載したい場合、その情報を非表示にしておいて、読みたい人だけに読ませるようにするテクニックをお伝えします。

CSSだけで開閉ボタンを実現する

今回はCSSとhtmlだけで次のような開閉ボタンを作成します。

開閉ボタン例1
詳しい情報はこちら!

開かれた状態です。
開閉ボタン例2
詳しい情報

開かれた状態です。

[open]([+])または[close]([-])をクリックすると、下方に設置されたボックスが表示・非表示されます。

開閉ボタンのhtml

htmlは、次のようになります。

開閉ボタン例1のhtml

<div>詳しい情報はこちら!<input id="b0" type="checkbox" class="ocbutton"><label for="b0"></label>
<div id="b0_content"  class="oc_content">
開かれた状態です。※1
</div></div>

開閉ボタン例2のhtml

<div><input id="b0" type="checkbox" class="ocbutton"><label for="b0"></label>詳しい情報
<div id="b0_content"  class="oc_content">
開かれた状態です。※1
</div></div>

例1と2の違いは、開閉ボタンの前後に表示する文字の位置だけです。

WordPressはページ表示時に勝手にタグを挿入します。
上のhtmlを改行するとタグの挿入箇所が増えて、動作しなくなります。
<div>から</label>までは、改行を入れずに一行で記述してください。

※1部分は、自由にタグを使って大丈夫です。

開閉ボタンのcss

次はcssです。

開閉ボタン例1のcss

.ocbutton{
            display: none;
            cursor: pointer;
}
.ocbutton + label{
            cursor: pointer;
}
.ocbutton + label:hover{ /* マウスがボタンの上にある時 */
            border-bottom:1px dotted #888 ;
}
.ocbutton + label:before{ /* 非表示時の文字 ※3*/
            content:"[open]"
}
.ocbutton:checked + label:before{  /* 表示時の文字 ※3 */
            content:"[close]"
}
.oc_content{
            display: none;
}
#b0:checked ~ #b0_content{
            display:block;
}
.oc_content{ /* 表示非表示されるボックスの外観 ※2*/
            border:1px solid #000;margin:1em;padding:1em;
}
.ocbutton ~ p:first-of-type{ /* WordPressのみ(自動で付加されるPを非表示)※1 */
  display: none;
}

※1はWordPressが自動で挿入した最初のPタグを非表示しています。
これにより、Pタグによる開閉ボタンとボックスの隙間を削除(非表示)します。

今回はわかりやすいように、表示非表示されるボックスの外観(※2)を設定しています。
この記述は削除しても問題ありません。

開閉ボタン例2は、※3を変更しています。

開閉ボタン例2のcss(差分)

.ocbutton + label:before{ /* 非表示時の文字 */
            content:"[+]"
}
.ocbutton:checked + label:before{  /* 表示時の文字 */
            content:"[-]"
}

画像を表示する

開閉ボタンに文字ではなく画像を表示したい場合、次のように記述します。

開閉ボタンに画像を表示

.ocbutton + label:before{ /* 非表示時の文字 */
            content: url(画像のURL)
}
.ocbutton:checked + label:before{  /* 表示時の文字 */
            content: url(画像のURL)
}

開閉ボタンに画像例
←お宝を開け!!

開かれた状態です。

絵文字(Font Awesome)を表示する

Font Awesomeを開閉ボタンに使用するときは、次のようにする。

開閉ボタンにFont Awesomeを使用

.ocbutton + label:before{
            font-family: "Font Awesome 5 Free";
            content: "\f023";
            font-weight: 900;
}
.ocbutton:checked + label:before{
            font-family: "Font Awesome 5 Free";
            content: "\f09c";
            font-weight: 900;
}

font-familyとfont-weightは、使用するアイコンのスタイルによって変更します。

style font-family font-weight
Solid Font Awesome 5 Free 900
Regular Font Awesome 5 Pro 400
Light Font Awesome 5 Pro 300
Duotone Font Awesome 5 Duotone 900
Brands Font Awesome 5 Brands 400

なおFont Awesomeを使用するには、ページ内に次の記述がしてある必要があります。

<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet">
↑これがないと表示されないので注意!!

簡単な解説

今回紹介した開閉ボタンの例で、一番重要なのが次のcss部分です。

一番重要なcss部分

.oc_content{
            display: none;
}
#b0:checked ~ #b0_content{
            display:block;
}

.oc_contentは開閉されるエリアで、通常は非表示(display: none)です。

#b0はチェックボックスですが、ここでは非表示にしてあります。
このままではチェックボックスを操作できませんが、labelタグを関連付けることで操作可能になります。

チェックボックスがチェック状態のとき:checked 疑似クラスセレクターが適用されます。

その後に続く『 ~ 』は一般兄弟結合子と呼ばれるもので、後に続く同じ階層の要素に適用されます。
今回は次のような構造になっているので、input#b0とdiv:#b0_contentは同じ階層です。

div┬input#b0
     ├label
     └div:#b0_content または .oc_content

そのためチェックボックスがチェック状態のとき、『#b0:checked ~ #b0_content』が適用されます。

チェック状態は開かれた状態ですので、非表示『display: none』を打ち消すために、 『display: block』を指定しています。

複数の開閉ボタンを設置する場合

同じWebページに複数の開閉ボタンを設置する場合、cssとhtmlに少し変更が必要です。
次のように、赤い文字の部分を書き換えます。

複数の開閉ボタンを設置 html

<div>詳しい情報はこちら!<input id="b0" type="checkbox" class="ocbutton"><label for="b0"></label>
<div id="b0_content"  class="oc_content">
開かれた状態です。
</div></div>

<div>詳しい情報はこちら!<input id="b1" type="checkbox" class="ocbutton"><label for="b1"></label>
<div id="b1_content"  class="oc_content">
開かれた状態です。
</div></div>

inputのidとlabelのforは、同じ文字列を指定します。
divのidは、inputのidと異なる文字列を指定します。
なお、これらの文字列は、他の開閉ボタンと異なるものにしてください。

次にcssを次のように変更します。

複数の開閉ボタンを設置 css(差分)

#b0:checked ~ #b0_content,
#b1:checked ~ #b1_content{
            display:block;
}

赤い部分が追加された内容です。
#b1は、inputのidとlabelのforです。
#b1_contentは、divのidです。

さらに開閉ボタンを増やしたいときは、同じように追加していきます。

複数の開閉ボタン
詳しい情報はこちら!

開かれた状態です。
詳しい情報はこちら!

開かれた状態です。
詳しい情報はこちら!

開かれた状態です。
詳しい情報はこちら!

開かれた状態です。

文字が異なる複数の開閉ボタンを設置したいとき

同じページに、文字が異なる開閉ボタンを複数設置するときは少し面倒です。

まずは複数の開閉ボタンを設置する場合と同じようにID等を変更します。
さらにinputのclassに、他で使用していない新しいクラス名(ここではocbutton2)を記述します。

文字が異なる複数の開閉ボタンを設置 html

<div>詳しい情報はこちら!<input id="b0" type="checkbox" class="ocbutton"><label for="b0"></label>
<div id="b0_content"  class="oc_content">
開かれた状態です。
</div></div>

<div><input id="b1" type="checkbox" class="ocbutton ocbutton2"><label for="b1"></label>詳しい情報
<div id="b1_content"  class="oc_content">
開かれた状態です。
</div></div>

<div><input id="b2" type="checkbox" class="ocbutton ocbutton2"><label for="b2"></label>詳しい情報
<div id="b2_content"  class="oc_content">
開かれた状態です。
</div></div>

上の例では、通常のボタン一つ、文字を変更したボタンを二つ設置しています。

次に開閉ボタンのcssを記述します。

文字が異なる開閉ボタンのcss html

.ocbutton.ocbutton2 + label:before{
            content:"[+]"
}
.ocbutton.ocbutton2:checked + label:before{
            content:"[-]"
}
#b0:checked ~ #b0_content,
#b1:checked ~ #b1_content,
#b2:checked ~ #b2_content{ /* ※1 */
            display:block;
}

赤文字は、新しいクラス名です。
こうすることで、classにocbuttonとocbutton2が記述してあるタグ全てに、上のcssが適用されます。

※1については、複数の開閉ボタンを設置する場合を見てください。

文字が異なる複数の開閉ボタンを設置
詳しい情報はこちら!

開かれた状態です。
詳しい情報

開かれた状態です。
詳しい情報

開かれた状態です。

動きにアニメーションを適用

最後に動きのある開閉ボタンを紹介します。

ただしブラウザに少なからず負担を与えます。
記事の読者像などを念頭に置いて、本当に必要なのかを考えた方がいいと思います。

上下左右に開閉

まずは上下左右に開閉させてみます。

htmlは、共通で次のものを使用します。

上下左右に開閉する html

<div>詳しい情報はこちら!<input id="b0" type="checkbox" class="ocbutton"><label for="b0"></label>
<div id="b0_content"  class="oc_content"> <!-- ※1 -->
        <div style="width:100%;padding:1em;border:1px solid #888;"> <!-- ※2 -->
            開かれた状態です。
        </div>
</div></div>

 <!--  -->はコメントなので削除しても大丈夫です。

今回は※1のdivタグが開閉します。
このタグのcssにpadding:0以外を設定すると余分な隙間ができるので、内側にdiv(※2)を作成し、こちらにpaddingを設定しています。

下から上に閉じる

閉じるときは下から上へ。
開くときは上から下に動きます。

下から上に閉じる例
詳しい情報はこちら!

開かれた状態です。
下から上に閉じる css

.oc_content{
            transition: max-height .5s ease;
            max-height: 0;
            padding:0;
            overflow:hidden;
            margin: 1em 0;
}
#b0:checked ~ #b0_content{
            max-height: 100vh;
}

上のcssは高さが可変のときを想定しています。

高さが固定の場合は上の例でもOKですが、次のように変更するとパフォーマンスがよくなります。

.oc_content{
            transition: height .5s ease;
            height: 0;
            /* 省略 */
}
#b0:checked ~ #b0_content{
            height300px;
}

右から左に閉じる

閉じるときは右から左へ。
開くときは左から右に動きます。

右から左に閉じる
詳しい情報はこちら!

開かれた状態です。
右から左に閉じる css

.oc_content{
            animation: .5s ease-in 0s 1 normal oc_content_close;
            padding:0;
            width: 0;
            overflow:hidden;
            margin: 1em 0;
            height: 0;
}
@keyframes oc_content_close {
            0% { width: 100%;height: 100px;}
            80% { width: 0; height: 100px;}
            100% { width: 0; height: 0;}
}

#b0:checked ~ #b0_content{
            animation: .5s ease-in 0s 1 normal r2_content_open;
            width: 100%;
            height: 100px;
}
@keyframes r2_content_open{
            0% { height: 0;width: 0;}
            20% { height: 100px; width: 0;}
            100% { height: 100px;width: 100%;}
}

.oc_content div{
            height: 100px;
}

右から左に閉じるとき、幅が小さくなるにつれて高さが増えていきます。
見た目がよくないので、高さを100pxに固定しています。(赤字の部分)
適宜変更してください。

上下左右にスライド

今度は上下左右にスライドしてみます。

htmlは、共通で次のものを使用します。

上下左右に開閉する html

<div>詳しい情報はこちら!<input id="b0" type="checkbox" class="ocbutton"><label for="b0"></label>
<div id="b0_content"  class="oc_content"> <!-- ※1 -->
        <div style="width:100%;padding:1em;border:1px solid #888;"> <!-- ※2 -->
            開かれた状態です。
        </div>
</div></div>

※2をスクロールさせます。
そのため、上下左右に開閉と同じhtmlですが、今回は※2が必須です。

下から上にスライド

下から上にスライド
詳しい情報はこちら!

開かれた状態です。
下から上にスライド css

.oc_content{
            animation: .7s ease-in 0s 1 normal oc_content_close1;
            overflow: hidden;
            position: relative;
            padding:0;
            margin: 1em 0;
            height: 0;
}
@keyframes oc_content_close1 {
            0% { height: 110px;}
            60% { height: 110px;}
            100% { height: 0; }
}
.oc_content > div{
            animation: .7s ease-in 0s 1 normal oc_content_close2;
            top: -110%;
            position: absolute;
            height: 100px;
            opacity: 0;
}

@keyframes oc_content_close2 {
            0% { top: 0; opacity: 1;}
            60% { top:-110%; opacity: 1;}
            65% { top:-110%; opacity: 0;}
            100% { top:-110%;  opacity: 0;}
}

#b0:checked ~ #b0_content{
            animation: .7s ease-in 0s 1 normal oc_content_open1;
            height: 110px;

}
@keyframes oc_content_open1 {
            0% { height: 0;}
            40% { height: 110px;}
            100% { height: 110px; }
}

#b0:checked ~ #b0_content > div{
            animation: .7s ease-in 0s 1 normal oc_content_open2;
            top: 0;
            opacity: 1;
}
@keyframes oc_content_open2 {
            0% { top: -110%;  opacity: 0;}
            40% { top:-110%; opacity: 0;}
            45% { top:-110%; opacity: 1;}
            100% { top:0;  opacity: 1;}
}

内側のdivを上下にスライドしたあと、外側のdivの高さを変更しています。
同時に2つのアニメーションを実行しているため、少し動きが重いかもしれません。

上から下にスライド

上から下にスライド
詳しい情報はこちら!

開かれた状態です。
上から下にスライド css

.oc_content{
            animation: .7s ease-in 0s 1 normal oc_content_close1;
            overflow: hidden;
            position: relative;
            padding:0;
            margin: 1em 0;
            height: 0;
}
@keyframes oc_content_close1 {
            0% { height: 110px;}
            60% { height: 110px;}
            100% { height: 0; }
}
.oc_content > div{
            animation: .7s ease-in 0s 1 normal oc_content_close2;
            bottom: -110%;
            position: absolute;
            height: 100px;
            opacity: 0;
}

@keyframes oc_content_close2 {
            0% { bottom: 0; opacity: 1;}
            60% { bottom:-110%; opacity: 1;}
            65% { bottom:-110%; opacity: 0;}
            100% { bottom:-110%;  opacity: 0;}
}

#b0:checked ~ #b0_content{
            animation: .7s ease-in 0s 1 normal oc_content_open1;
            height: 110px;

}
@keyframes oc_content_open1 {
            0% { height: 0;}
            40% { height: 110px;}
            100% { height: 110px; }
}

#b0:checked ~ #b0_content > div{
            animation: .7s ease-in 0s 1 normal oc_content_open2;
            bottom: 0;
            opacity: 1;
}
@keyframes oc_content_open2 {
            0% { bottom: -110%;  opacity: 0;}
            40% { bottom:-110%; opacity: 0;}
            45% { bottom:-110%; opacity: 1;}
            100% { bottom:0;  opacity: 1;}
}

赤い文字だけが変更されています。

こちらはbottom方向に変化させているだけで、下から上にスライドと同じです。

右から左にスライド

右から左にスライド
詳しい情報はこちら!

開かれた状態です。
右から左にスライド css

.oc_content{
            animation: .7s ease-in 0s 1 normal oc_content_close1;
            overflow: hidden;
            position: relative;
            padding:0;
            margin: 1em 0;
            height: 0;
}
@keyframes oc_content_close1 {
            0% { height: 110px;}
            60% { height: 110px;}
            100% { height: 0; }
}
.oc_content > div{
            animation: .7s ease-in 0s 1 normal oc_content_close2;
            left: -110%;
            position: absolute;
            height: 100px;
            opacity: 0;
}

@keyframes oc_content_close2 {
            0% { left: 0; opacity: 1;}
            60% { left:-110%; opacity: 1;}
            65% { left:-110%; opacity: 0;}
            100% { left:-110%;  opacity: 0;}
}

#b0:checked ~ #b0_content{
            animation: .7s ease-in 0s 1 normal oc_content_open1;
            height: 110px;

}
@keyframes oc_content_open1 {
            0% { height: 0;}
            40% { height: 110px;}
            100% { height: 110px; }
}

#b0:checked ~ #b0_content > div{
            animation: .7s ease-in 0s 1 normal oc_content_open2;
            left: 0;
            opacity: 1;
}
@keyframes oc_content_open2 {
            0% { left: -110%;  opacity: 0;}
            40% { left:-110%; opacity: 0;}
            45% { left:-110%; opacity: 1;}
            100% { left:0;  opacity: 1;}
}

こちらも赤い文字だけが変更されています。

左から右にスライド

左から右にスライド
詳しい情報はこちら!

開かれた状態です。
左から右にスライド css

.oc_content{
            animation: .7s ease-in 0s 1 normal oc_content_close1;
            overflow: hidden;
            position: relative;
            padding:0;
            margin: 1em 0;
            height: 0;
}
@keyframes oc_content_close1 {
            0% { height: 110px;}
            60% { height: 110px;}
            100% { height: 0; }
}
.oc_content > div{
            animation: .7s ease-in 0s 1 normal oc_content_close2;
            right: -110%;
            position: absolute;
            height: 100px;
            opacity: 0;
}

@keyframes oc_content_close2 {
            0% { right: 0; opacity: 1;}
            60% { right:-110%; opacity: 1;}
            65% { right:-110%; opacity: 0;}
            100% { right:-110%;  opacity: 0;}
}

#b0:checked ~ #b0_content{
            animation: .7s ease-in 0s 1 normal oc_content_open1;
            height: 110px;

}
@keyframes oc_content_open1 {
            0% { height: 0;}
            40% { height: 110px;}
            100% { height: 110px; }
}

#b0:checked ~ #b0_content > div{
            animation: .7s ease-in 0s 1 normal oc_content_open2;
            right: 0;
            opacity: 1;
}
@keyframes oc_content_open2 {
            0% { right: -110%;  opacity: 0;}
            40% { right:-110%; opacity: 0;}
            45% { right:-110%; opacity: 1;}
            100% { right:0;  opacity: 1;}
}

こちらも赤い文字だけが変更されています。