[css js]最初は一部だけ表示して、「もっと見る」で全文表示するやつを作る方法

歯がゆいところが残るけど。

基本形

HTMLは無難にこんな感じ。

<div class="wrap">
    <div class="inner">中身</div>
</div>
<span class="trigger">もっと見る</span>

.wrapで表示領域を調整して、.triggerをクリックしたら高さ変更で全部表示。
.innerに文章とかを格納する。

.wrap{
    overflow: hidden;
    height: 100px;
}

overflow:hidden;と高さの実数を与えることで中身のボリュームを無視して一部表示が可能になる。

.wrapに指定するheightをいじることで、表示領域を操作するって感じになる。

アニメーションなしの開閉

割と楽。

<div class="wrap close">
    <div class="inner">中身</div>
</div>
<span class="trigger">もっと見る</span>
.wrap{
    overflow: hidden;
}
.wrap.close{
    height: 100px;
}
$('.trigger').click(function(){
    $('.wrap').removeClass('close');
})

.closeの有無が高さの切り替えになる。初心者にもわかり易い内容で導入できるって意味ではいいんだけど。

問題点というか課題というかがあって、これにはアニメーションが付けられない。cssのtransitionは開閉時それぞれに実数を与えてないと動作しない。

例えば、100px→200pxなら動きが付けられるけど、100px→100%とか100px→autoとかだと動きはつかない。上記の場合は100px指定する/しないって内容だから無理ってことになる。

アニメーションありの開閉

視覚的な要素はとても大切で、クリックしたらとんでもない量が一気に表示されるとビビるし何が起こったんだ??みたいに混乱する可能性もある。極端に言えば、アニメーションするからこそ隠れた部分が表示されてることがわかるようになる。

ということでアニメーションを付けたいんだけど、完全な開閉じゃなくてちょい見せからの全部表示なので、display:none;じゃないんで、jQueryのslideDownは使えない。スライド効果はcssでやっていく必要がある。jQueryはそれのサポートに終始することになる。

<div class="wrap">
    <div class="inner">中身</div>
</div>
<span class="trigger">もっと見る</span>
.wrap{
    overflow: hidden;
    transition: height 0.5s ease;
}
var wrapHeight = $('.wrap').height();
$('.wrap').css('height','100px');
$('.trigger').click(function(){
    $('.wrap').css('height', wrapHeight + 'px');
})

こんな感じで、ちょい見せは100pxに指定した。

当然ながらこれには問題があって、WEBページの仕様上jsの処理は後回しになる。基本的にhtmlとcssの内容が優先されるんで、つまり、読み込み時一瞬全部表示される。だからページの高さも一瞬変わる。とても格好悪いことになるというのを飲まなきゃいけない。

でもこれは仕方がなくて、表示時の高さを取得するためには一旦表示した状態を作る必要がある。

じゃあ諦めるしか無いのかっていうと、できるんだけどね。

<div class="wrap close">
    <div class="inner">中身</div>
</div>
<span class="trigger">もっと見る</span>
.wrap{
    overflow: hidden;
    transition: height 0.5s ease;
}
.wrap.close{
    height: 100px;
}
var wrapHeight = $('.wrap .inner').outerHeight();
$('.trigger').click(function(){
    $('.wrap').removeClass('close');
    $('.wrap').css('height', wrapHeight + 'px');
})

overflow:hidden;だから子要素の高さは生きてるから、そっちの高さを取得したら最初から格納状態にできるじゃん!って話。視覚的にこっちが良い。

こっちにも注意点があって、展開時に.wrapと.innerの高さとイコールにならないデザインをしちゃったら調整が必要になる。.wrapにbox-sizing: border-box;とpaddingがついてるとか、.innerにmarginとかborderをやってたらどうなんだよってことで、とりあえずのルールとして.wrapで余白調整はしない、.innerの高さの取得はouterHeight()が無難かなって感じに。

どっちも装飾しないで開閉ギミックの入れ子専用として扱うのがいいと思います。

今回は開閉部のみに注目した内容なので、押した.triggerを非表示にしたいとか、展開後にまた戻せるようにしたいとか、そういうのがあったら付け加えてやっていってください。

コメント

タイトルとURLをコピーしました