3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【JavaScript / CSS】1行目だけ見えているアコーディオンの作り方

Last updated at Posted at 2021-12-15

こんにちは、ウェブエンジニアのmasakichiです。
需要があるかわからない程度のtipsなどを書いています。

今回は1行目だけテキストが見えているアコーディオンに挑戦します。

#なにそれ?
こんなアコーディオンです。
テキストの1行目だけ表示されていて、タイトル部分をクリックすると全文が表示されます。

sample.jpg

#なぜ書いた?
実際、すごく簡単なコードなので記事にするほどでもないのですが、ググって見つけたサンプルが下記のようなコードが多かったので。



こんなHTMLがあるとして、

HTML
<dl class="accordion">
	<dt>
		TITLE
	</dt>
	<dd>
		<p>
			TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT
			TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT 
			TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT 
			TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT
		</p>
	</dd>
</dl>


こんなCSSを記述して

SCSS
.accordion{
	max-width: 300px;
	margin: 20px auto;
	dt{
		padding: 1em;
		background-color: #ccc;
	}
	dd{
		background-color: #eeeeee;
		height: 1em;
		overflow: hidden;
		transition: .3s;
	}
}
.accordion.active{
	dd{
		height: auto;
	}
}


JavaScriptでクラスの付け替えを実装して完成!

JavaScript
$(function(){
    $('.accordion').on('click',function(e){
        if(!$(e.target).parents().is('dt') && e.target !== $(this).find('dt').get(0)){
            return;
        }
        $(this).toggleClass('active');
    });
});

いや、まぁいいんですけど...
お気づきの方もいらっしゃると思うのですが、アニメーションはガン無視なのですよ。

height:autoにしたところでtransitionはかからず。
中にはheightの数値を決め打ちで◯◯pxとしてるのもあって、これはたしかにtransitionかかるのですが。。。

数値決め打ちってなぁ。。。行数増えたらどうすんの?と思い、自作することにしました(最初から自作しろ)

#clip-pathを使ってみる
まず考えたのが、heightがダメなら、切り抜き範囲を変えてみたらどうかなと思い、clip-pathを使うことにしました。

以下HTML部分は以前のものと一緒です。

SCSS
.accordion{
	max-width: 300px;
	margin: 20px auto;
	dt{
		padding: 1em;
		background-color: #ccc;
	}
	dd{
		background-color: #eeeeee;
		clip-path: inset(0 0 calc(100% + -1em) 0);
		transition: .3s;
	}
}
.accordion.active{
	dd{
		clip-path: inset(0 0 0 0);
	}
}
JavaScript
$(function(){
    $('.accordion').on('click',function(e){
        if(!$(e.target).parents().is('dt') && e.target !== $(this).find('dt').get(0)){
            return;
        }
        $(this).toggleClass('active');
    });
});

これで無事にtransitionもかかって、しっかりテキストの高さ分アコーディオンしてくれるようになりました。
しかし、問題が。。。

まず、下記のようにclip-pathで切り抜いたとしても高さがなくなるわけではないので、もし下に別の要素来るとしたら変な隙間が空いてしまいます。
sample.jpg

そしてさらに、clip-pathはIE11に対応しておらず。。。
うーん。これだとかなり使い道が限定されてしまいます。

#JavaScriptで実装する
はい。結局、JS使って実装しました。

他にもいろいろCSSプロパティをググってみたのですが、いいものが見つからず。。。
もしCSSだけでいけるよ!ってかたがいらっしゃいましたら是非教えてください

m(_ _)m < なにとぞ

それでは実装例です。

先ほど同様に、HTML部分は以前のものと一緒です。

SCSS
.accordion{
	max-width: 300px;
	margin: 20px auto;
	dt{
		padding: 1em;
		background-color: #ccc;
	}
	dd{
		position: relative;
		background-color: #eeeeee;
		transition: .3s;
		padding-bottom: 1em;
		overflow: hidden;
		p{
			position: absolute;
			top: 0;
			left: 0;
		}
	}
}
JavaScript
$(function(){
    $('.accordion').on('click',function(e){
        if(!$(e.target).parents().is('dt') && e.target !== $(this).find('dt').get(0)){
            return;
        }
        $(this).toggleClass('active');
        let contentsH = $(this).find('p').height();

        if($(this).hasClass('active')){
            $(this).find('dd').css({
                "padding-bottom": contentsH + "px"
            });
        }else{
            $(this).find('dd').removeAttr('style');
        }
    });
});

特に説明が必要なくらいのコードではないかと思いますが、要点として下記です。

  • クリックイベント時に親要素にactiveクラスを付け替えする
  • クリックイベント時にアコーディオン箇所の高さを取得する
  • activeクラスの有無によってアコーディオン箇所にスタイルをあてる

んー。なにかいいCSSはないものだろうか。。。

今日は以上です!

#追記 line-heightを使う
コメントにて@nagtkkさんからご紹介頂きました。
ありがとうございます。感謝しかありませんm(_ _)m

line-heightの調整でアコーディオンが実現可能です。
ご好意でリンクを貼っても大丈夫とのことでしたので、下記codepenをご参考ください。

内容物にボタンなどが入り込むともう少し工夫が必要ですが、テキストなどのあくまで単純なものであれば、しっかりとクラスの付け替えのみで実装可能です。

See the Pen line-height-accordion by nagtkk (@nagtkk) on CodePen.

3
3
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?