トリガーより下に開閉する方法はネットで少し調べてみると出てきたのですが、トリガーより上に開く方法がなかなかでてこなかったのでこちらでもまとめておきたいと思います。
ついでによく使うわりに毎回ググってしまいがちな、cssのみで実装できる開閉時にアイコンが切り替わる方法とチェックボックスのデザインも合わせて自分のメモとしてのせておきたいと思います!
1、トリガーより上に開くアコーディオン
こちらはjqueryを使用します。
私はjsとcssで同じclassやIDを指定しないようにしています。
どちらの修正が発生しても影響のない方が無難ですね!
今回はjs側の指定にはIDを使用しました。またID名も後々分かりやすいようjs-xxxと命名。
HTML
<div class="demo"> <div class="demo__body" id="js-demo-body"> <!-- 2、CSSのみで実装できる開閉時アイコンが切り替わるアコーディオンが入ります --> </div> <div class="demo__link" id="js-demo-link"> <p class="demo__text" id="js-demo-text">開閉リンク <i class="icon-plus"></i> </p> </div> </div>
jquery
< script > $(function () { $("#js-demo-body").hide(); $("#js-demo-text").click(function () { $("#js-demo-link").prev().slideToggle(); $(this).toggleClass("close"); }); }); < /script>
CSS
.demo { margin: 20px; color: #444; } .demo__link { position: relative; } .demo__text { display: inline-block; margin-right: 15px; color: #f89496; border-bottom: 1px solid #f89496; text-decoration: none; transition: all .2s ease 0s; font-size: 14px; font-size: 1.4rem; } .demo__text.close .icon-plus:after { display: none; } .demo__text .icon-plus { display: inline-block; margin-left: 3px; width: 14px; height: 14px; position: absolute; background-color: #f89496; border-radius: 2px; } .demo__text .icon-plus:before { width: 10px; height: 1px; position: absolute; top: 6px; left: 2px; color: #fff; background-color: currentColor; content: ''; } .demo__text .icon-plus:after { width: 10px; height: 1px; position: absolute; top: 6px; left: 2px; color: #fff; background-color: currentColor; content: ''; -webkit-transform: rotate(90deg); transform: rotate(90deg); } .demo__body { margin: 15px 0; }
参考サイト:「jQuery:トリガーより上部に開くアコーディオン – WordPress Note」
参考サイトにjqueryの内容が説明されています!
こういった素晴らしい参考サイトが沢山あって本当に助かります。。。
<div class=”demo__body”>は最初は隠しておき、
<div class=”demo__text”>をクリックすると、
<div class=”js-demo-link”>より前のタグ.prev()が
.slideToggle()します。
そして、$(this).toggleClass(“close”);で、ボタンをクリックするたびに.closeのクラスを.demo__textに追加したり、除去したりします。
2、CSSのみで実装できる開閉時アイコンが切り替わるアコーディオン
HTML
<div class="demo"> <div class="demo__body" id="js-demo-body"> <ul class="demo__list"> <li class="demo__item"> <input class="demo__item__input" id="demo01" type="checkbox"> <label class="demo__item__label" for="demo01">項目テキスト01</label> <div class="demo__item__body"> <!-- 3が入ります --> </div> </li> </ul> </div> <!-- 1、トリガーより上に開くアコーディオンが入ります --> </div>
CSS
.demo__list { border: 1px solid #ccc; } .demo__item__label { display: block; padding: 13px 10px; position: relative; border-bottom: 1px solid #eee; white-space: nowrap; text-overflow: ellipsis; cursor: pointer; font-size: 14px; font-size: 1.4rem; } .demo__item__label:after { position: absolute; right: 10px; color: #aaa; content: ' '; font-size: 18px; font-size: 1.8rem; font-weight: bold; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; width: 8px; height: 8px; border-top: 2px solid #f89496; border-right: 2px solid #f89496; -webkit-transform: rotate(135deg); transform: rotate(135deg); } .demo__item:last-of-type .demo__item__label { border-bottom: none; } .demo__item__input { display: none; } .demo__item__input:checked~label:after { -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .demo__item__input:checked~.demo__item__body { height: auto; } .demo__item__body { height: 0; overflow: hidden; z-index: 10; }
切り替わるテキストにinputとlabelタグを使用し、デザインをlabelに適応させます。
demo__item__inputは非表示(display:none;)にします。
demo__item__labelにデザインを指定し、擬似要素afterにアイコンデザインを指定します。
demo__item__input:checked~label:afterで切り替え後のアイコンデザインを指定します。
demo__item__bodyははじめheight:0;で非表示となっていますが、demo__item__input:checked~.demo__item__bodyでheight:auto;にして表示させています。
※demo__item__inputのchecked要素を使用して、クリック前後のデザインを指定しています!
3、チェックボックスのデザイン(下階層付き)
HTML
<ul class="demo__child-list"> <li class="demo__child-item"> <input type="checkbox" name="" id="list01-01" value="" disabled=""> <label for="list01-01" class="demo__child-label">詳細テキスト01 </label> </li> <li class="demo__child-item"> <input type="checkbox" name="" id="list01-02" value=""> <label for="list01-02" class="demo__child-label">詳細テキスト02 </label> </li> </ul> </div> </li> <li class="demo__item"> <input class="demo__item__input" id="demo02" type="checkbox"> <label class="demo__item__label" for="demo02">項目テキスト02</label> <div class="demo__item__body"> <ul class="demo__child-list"> <li class="demo__child-item"> <input type="checkbox" name="" id="list02-01" value=""> <label for="list02-01" class="demo__child-label">詳細テキスト01 </label> </li> <li class="demo__child-item"> <input type="checkbox" name="" id="list02-02" value=""> <label for="list02-02" class="demo__child-label">詳細テキスト02 </label> <ul class="demo__child-list"> <li class="demo__child-item"> <input type="checkbox" name="" id="list02-02-01" value=""> <label for="list02-02-01" class="demo__child-label">詳細テキスト02-01 </label> </li> <li class="demo__child-item"> <input type="checkbox" name="" id="list02-02-02" value=""> <label for="list02-02-02" class="demo__child-label">詳細テキスト02-02 </label> </li> </ul> </li> <li class="demo__child-item"> <input type="checkbox" name="" id="list02-03" value=""> <label for="list02-03" class="demo__child-label">詳細テキスト03 </label> </li> </ul> </div> </li> <li class="demo__item"> <input class="demo__item__input" id="demo03" type="checkbox"> <label class="demo__item__label" for="demo03">項目テキスト03</label> <div class="demo__item__body"> <ul class="demo__child-list"> <li class="demo__child-item"> <input type="checkbox" name="" id="list03-01" value="" disabled=""> <label for="list03-01" class="demo__child-label">詳細テキスト01 </label> </li> <li class="demo__child-item"> <input type="checkbox" name="" id="list03-02" value=""> <label for="list03-02" class="demo__child-label">詳細テキスト02 </label> </li> </ul> </div> </li> </ul>
CSS
.demo__child-list { border-bottom: 1px solid #eee; } .demo__item:last-of-type .demo__child-list { border-top: 1px solid #eee; border-bottom: none; } .demo__child-item { display: block; width: 100%; height: auto; border-bottom: 1px dotted #eee; } .demo__child-item:last-of-type { border-bottom: none; } .demo__child-item input[type='checkbox'] { display: none; } .demo__child-item .demo__child-list { border-top: 1px dotted #eee; border-bottom: none; } /* 下階層のデザイン調整 */ .demo__child-item .demo__child-list .demo__child-label { padding-left: 58px } .demo__child-item .demo__child-list .demo__child-label:before { left: 40px; } .demo__child-item .demo__child-list input[type='checkbox']:checked+.demo__child-label:after { left: 45px; } /* チェックボックスのデザイン */ .demo__child-label { display: block; padding: 13px 10px 13px 38px; position: relative; vertical-align: middle; font-size: 14px; font-size: 1.4rem; } .demo__child-label:before { margin-top: -6px; width: 10px; height: 10px; position: absolute; top: 50%; left: 20px; border: 1px solid #ddd; content: ''; } input[type='checkbox']:checked+.demo__child-label:after { margin-top: -8px; width: 4px; height: 10px; position: absolute; top: 50%; left: 25px; z-index: 1; border: 2px solid #f89496; border-width: 0 2px 2px 0; content: ''; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); transform: rotate(45deg); } input[type='checkbox']:disabled+.demo__child-label { color: #aaa; }
こちらも「2、CSSのみで実装できる開閉時アイコンが切り替わるアコーディオン」と同様input要素を非表示にし、label要素にデザインを指定していきます。
チェックアイコンは擬似要素before、afterで指定しています。
inputのchecked時にクリック後のデザインを指定しています。
要素をクリックした時のアイコンの切り替えはinputとlabelをうまく利用するとjsを使用せずに実装することができて便利ですね!!次回はforme要素のデザインをまとめていければと思います!!