CSSで実装!開閉エリアの作り方と
サンプルコード3つ

2020-12-26

ここでは、長文などを折りたたんで隠しておき、「開く」ボタンで表示する開閉エリアのソースを紹介しています。

開閉エリアはCSSだけで実装可能!

ボタンのテキストを変更するタイプ、一部を表示して「もっと見る」タイプ、開閉ボタンを2つ設置するタイプの3つをまとめています。

早速見ていきましょう!

\項目をタップするとジャンプできます/

CSSでの基本的な開閉エリアの作り方

このページで使っている開閉エリアの基本的なサンプルとソースはこちらです。

「input」のチェックボックスと「label」を使ったシンプルなものです。

開閉エリア
HTML

<div class="open-box">
<input type="checkbox" id="switch" class="on-off" />
<label for="switch" class="open-label">開く</label>
<div class="open">
開閉エリア
</div>
</div>

「input」にIDをつけて、「label for」で「input」のIDを指定します。

これで、このラベルをタップすると指定した「input」のチェックボックスにチェックが入るようになります。

あとは、CSSでチェックが入った時の動作を指定していきます。

CSS

/*inputを非表示*/
input[type="checkbox"].on-off{
  opacity: 0;
}

/*ラベル(「開く」ボタン)*/ .open-label{ margin: 0 1.5em; padding: 0.8em; display: block; color: #fff; font-weight: bold; text-align: center; box-shadow: 0 2px 0 2px #aaa; background: #fcae11; border-radius: 10px; } /*ボタンっぽい効果*/ .open-label:active{ box-shadow: 0 0 0 0; } .open-label:hover{ background: -webkit-linear-gradient(bottom, #fff4e0 1%,orange 80%); background: #fcbe11; }
/*開閉エリア*/ .open{ padding: 0 1em; height: 0; opacity: 0; transition: .5s; } /*「開く」をタップで表示*/ .on-off:checked ~ .open{ padding: 1.5em 1em; height: auto; opacity: 1; }

「.on-off:checked ~ .open」では、チェックボックスにチェックが入った時に、HTML上で「input」に続く要素をどう表示するかを指定できます。

ここでは「label」をタップしてチェックが入ると、非表示だった開閉エリアが表示されるように指定しています。

開閉エリアは「opacity: 0;」などであらかじめ非表示にしておき、チェックボックスにチェックが入ったら「opacity: 1;」などで表示しています。

「transition」で開閉にかける時間を指定して、開閉前後の「padding」に変化をつけることで、するっと表示される効果をつけています。

CSSだけで作る開閉エリア
「タップでテキスト変更」タイプ

ここからは、基本的なソースを、より実用向けに装飾した開閉エリアのソースコードを見ていきましょう。

こちらはさっきの開閉エリアと同じく、非表示エリアを「開く」ボタンで表示するタイプの開閉エリア。

違うのは、「タップで開く」ボタンをタップすると「タップで閉じる」にテキストが変わるところです。

ラベルのテキストをHTMLではなく、CSSファイルから疑似要素として指定する事で、タップした時にラベルテキストを変更できるようにしています。

HTML

<div class="open-box">
<input type="checkbox" id="switch" class="on-off" />
<label for="switch" class="open-label"></label>
<div class="open">
開閉エリア
</div>
</div>

CSS

/*inputを非表示*/
input[type="checkbox"].on-off{
  opacity: 0;
}
/*ラベル(「開く」ボタン)*/
.open-label{
  margin: 0 1.5em;
  padding: 0.8em;
  display: block;
  color: #fff;
  font-weight: bold;
  text-align: center;
  box-shadow: 0 2px 0 2px #aaa;
  background: #fcae11;
  border-radius: 10px;
}
/*エフェクト*/
.open-label:active{
  box-shadow: 0 0 0 0;
}
.open-label:hover{
  background: -webkit-linear-gradient(bottom, #fff4e0 1%,orange 80%);
  background: #fcbe11;
}
/*ラベルに表示するテキスト*/ .open-label::after{ content:'タップで開く'; } .on-off:checked ~ .open-label::after{ content: 'タップで閉じる'; }
/*開閉エリア*/ .open{ padding: 0 1em; height: 0; opacity: 0; transition: .5s; } /*「開く」をタップで表示*/ .on-off:checked ~ .open{ padding: 1.5em 1em; height: auto; opacity: 1; }

CSSだけで作る開閉エリア
「もっと読む」タイプ

こちらは、開閉エリアの一部を表示して、「開く」ボタンで全体を表示するタイプの開閉エリアです。

長いから一部をたたみたいけど、内容を少し見せておきたい時にベンリです。

このタイプは開くボタンが開閉エリアの下に来るので、長文な開閉エリアを閉じた時、閉じた高さの分だけ下のテキストが引っ張られて迷子になりやすいです。

そこで、ここでは「input」の位置を「position: absolute;」で開閉エリアの真ん中に指定して、閉じた時にテキストの表示位置が飛ばないようにしてあります。

これだけだと「input」要素が飛び出してしまうので、親要素であるdiv要素に「position: relative;」を指定して、表示位置を親要素内に限定しています。

HTML

<div class="open-box">
<input type="checkbox" id="switch" class="on-off" />
<div class="open">
開閉エリア
</div>
<label for="switch" class="open-label"></label>
</div>

CSS

/*inputを非表示 & 閉じた時の位置調整*/ .open-box{ position: relative; } input[type="checkbox"].on-off{ position: absolute; top: 50%; display: block; opacity: 0; }
/*ラベル(「開く」ボタン)*/ .open-label{ margin: 0 1.5em; padding: 0.8em; display: block; color: #fff; font-weight: bold; text-align: center; box-shadow: 0 2px 0 2px #aaa; background: #fcae11; border-radius: 10px; position: relative; } /*ボタンっぽい効果*/ .open-label:active{ box-shadow: 0 0 0 0; } .open-label:hover{ background: -webkit-linear-gradient(bottom, #fff4e0 1%,orange 80%); background: #fcbe11; } /*ラベルに表示するテキスト*/ .open-label::after{ content:'タップで開く'; } .on-off:checked ~ .open-label::after{ content: 'タップで閉じる'; }
/*開閉エリア*/ .open{ padding: 1em; border-radius: 8px; height: 300px; overflow: hidden; transition: .5s; position: relative; } .on-off:checked ~ .open{ padding: 1.5em 1em; height: auto; } /*開閉エリアにぼかしを乗せる*/ .open::before{ content:''; background: linear-gradient(to bottom, transparent,rgba(255,255,255,1)100%); position: absolute; top:0; left:0; right:0; bottom:0; z-index: 3; } /*開いたらぼかしを消す*/ .on-off:checked ~ .open::before{ background: none; z-index: -1; }

CSSだけで作る開閉エリア
「ボタン2つ」タイプ

こちらは、開閉エリアの上下に「開く」ボタンを置くタイプです。

閉じている時は上のボタンのみ表示されて、開閉エリアが開くと、エリア下に閉じるボタンが表示されます。

「開いたけど、読んだら閉じたい」という時もあるかも、と作ってみました。

HTML

<div class="open-box">
<input type="checkbox" id="switch" class="on-off" />
<label for="switch" class="open-label1"></label>
<div class="open">
開閉エリア
</div>
<label for="switch" class="open-label2"></label>
</div>

CSS

/*inputを非表示 & 閉じた時の位置調整*/ .open-box{ position: relative; } input[type="checkbox"].on-off{ position: absolute; top: 0; display: block; opacity: 0; }
/*ラベル(「開く」ボタン)*/ .open-label1, .open-label2{ margin: 0 1.5em; padding: 0.8em; display: block; color: #fff; font-weight: bold; text-align: center; box-shadow: 0 2px 0 2px #aaa; background: #fcae11; border-radius: 10px; } /*ボタンっぽい効果*/ .open-label1:active, .open-label2:active{ box-shadow: 0 0 0 0; } .open-label1:hover, .open-label2:hover{ background: -webkit-linear-gradient(bottom, #fff4e0 1%,orange 80%); background: #fcbe11; } /*ラベルに表示するテキスト*/ .open-label1::after{ content:'タップで開く'; } .open-label2::after, .on-off:checked ~ .open-label1::after{ content: 'タップで閉じる'; }
/*追加ボタン(開いた時だけ表示)*/ .open-label2{ display: none; } .on-off:checked ~ .open-label2{ display: block; }
/*開閉エリア*/ .open{ padding: 0 1em; height: 0; opacity: 0; transition: .5s; } /*「開く」をタップで表示*/ .on-off:checked ~ .open{ padding: 1.5em 1em; height: auto; opacity: 1; }

CSSだけで作る開閉エリア
うまく動かない時は?

私はたまにやってしまうのですが、「input」はpタグなどで挟んでしまうと、正常に動作しません。

私の場合は単純な閉じ忘れなのですが、HTMLタグを自動付与するエディタなどでは、意図しない場所にpタグがつく事もあります。

意外と見落としやすいので、開閉エリアがうまく動かない時は、「input」の前に閉じられていないpタグがないか、一度確認してみましょう。

また、同じID名がページ内にあるのもNGなので、複数の開閉エリアを使う時は「input」に割り振るID名が同じにならないように気をつけましょう。