Edited at

[HTML/CSS]チェックボックスの仕組みを使ってえだまめ無限プチプチをつくるぞ


この記事は

メニューじゃないハンバーガーを作れるCSSをつくった。

の記事で同僚がinputを使ってなんやらかわいいものを作っていたので、

私もinputを使ってえだまめが飛び出してくるを作ったぞ!!!


See the Pen
edamame
by Mayu Mameuda (@mayu-mameuda)
on CodePen.

さやの部分を押すとえだまめが飛び出してくるぞい。いっぱい押してほしい。

どうでもいいけど昔無限プチプチって流行ったよな・・・。


inputlabelの便利な仕組み

そもそもinputlabelは、よくお問い合わせフォームとかで

チェックボックスとかラジオボタンとかを作るときに使うやつだよな。



上のようなチェックボックスを作った時、inputlabelに関連付けをしてない場合

input部分をクリックしないと選択できないんだが、関連付けをするとlabelをクリックしても選択ができるぞ。

inputlabelの関連付けのやり方は簡単で、上のような項目なら

<input type="checkbox" name="choice" id="choice-1" checked>

<label for="choice-1">選択肢1</label>
<input type="checkbox" name="choice" id="choice-2">
<label for="choice-2">選択肢2</label>
<input type="checkbox" name="choice" id="choice-3">
<label for="choice-3">選択肢3</label>

こうやってinputidと、labelforの値を同じにすることで実装できるぞい!

便利じゃなあ。

あと当たり前だけど、今回の使い方で重要なので書いておく。

選択されたinputにはcheckedという値が付与されるぞ。

今回はこの仕組みを使って、無限なえだまめプチプチを作るぞい!




この説明でよくわからない人は下の記事がわかりやすいから読んでほしいぞ

【参考】フォーム部品とラベルを関連付ける


作るパーツだぞい

今回はこんな感じのパーツを重ねてこうしてこうじゃ。



作り方を解説していくぞい!


えだまめのさやをつくる


細長いさやの部分

えだまめのさやの上のカーブをどう表現しようかなと思ったんだが(もはやCSSじゃなくてイラスト作成の話みたいだ)、結局半円ぽいものに細っこい半円ぽいものを重ねる、という結論になった。

htmlとSCSS。

<div class="edamame"></div>

これだけ。細っこい半円の部分は:afterでつけてるよ。

SCSSはこうじゃ。

.edamame{

//えだまめの土台
position:relative;
background:#CBE850;
margin:80px auto 0;
width:180px;
height:50px;
border-radius:5px 5px 100px 100px;
&:after{
//上のカーブしている部分を作るための細っこい半円
content:"";
background:#FFEDAB;
width:180px;
height:10px;
border-radius:0 0 60px 100px;
position:absolute;
top:0;
left:0;
right:0;
}
}

えだまめの土台にposition:absoluteで細い半円をくっつけてるぞ。

えだまめの土台は上の方のカーブは小さめで、下の方はまるっとしているけど、これはborder-radiusを角ごとに指定しているからだよ!

角はそれぞれ、

border-radius:左上 右上 右下 左下

の順に指定できるぞ!!

細い半円は下の部分しか丸みが必要ないので、

0 0 60px 100px;として、右下と左下にだけborder-radiusをつけてるよ。


さやのぼこぼこの部分

さやのぼこぼこの部分は、黄緑の楕円3つを.saya-wrapで囲って.edamameposition:abosluteしていくぞ!

さらにこの時、.saya-wrapで囲った部分をz-index:1にすることで、細長いさやの部分より全てが上に重なるようにしておるぞ。

htmlとSCSSは後ほど載せるぞ。

そんで、この楕円3つがさっき説明したinputとlabelのlabelの部分になるぞい。


labelをクリックした時どうなってほしいか



本来はlabel押したらinputが選択されるってだけなのでこんなこと考える必要ないんだが、

今回はlabelをクリックしたときにinputcheckedになるその仕組みを利用して色々要素を追加していくというやつなので、labelをクリックしたときに何がどうなってほしいかを考えるぞい。

今回はずばり、

さやをクリックしたら、①さやに暗めの黄緑の楕円が重なる②そのあとでまめが飛び出す

っていう仕組みを作っていきたいぞ!!!




まずは、①さやクリックで暗めの黄緑の楕円が重なるって部分を作っていくぞ!!!


さやを押したら暗めの黄緑が爆誕してほしい



↑こうなってほしい

とりあえず一旦飛び出すまめのことは忘れて、さやの部分のhtmlとSCSSを載っけるぞ!!

<div class="edamame">

<div class="saya-wrap">
<input id="button-1" type="checkbox" name="saya-button">
<input id="button-2" type="checkbox" name="saya-button">
<input id="button-3" type="checkbox" name="saya-button">
<label class="saya saya--1" for="button-1">
<div class="saya__push saya__push--1"></div>
</label>
<label class="saya saya--2" for="button-2">
<div class="saya__push saya__push--2"></div>
</label>
<label class="saya saya--3" for="button-3">
<div class="saya__push saya__push--3"></div>
</label>
</div>
</div>

//.edamame部分のSCSSは上にあるので省略

.saya-wrap{
//さやを覆うラップ
position:absolute;
z-index:1;
}

%saya,.saya{
//さや
background:#CBE850;
width:60px;
height:46px;
border-radius:30px / 23px;
cursor:pointer;
position:absolute;
top:6px;
&--1{
@extend %saya;
left:20px;
}
&--2{
@extend %saya;
left:60px;
}
&--3{
@extend %saya;
left:100px;
}
&__push{
background:#BBD64A;
width:34px;
height:30px;
border-radius:17px / 15px;
position:absolute;
transform:translateX(-50%) translateY(-50%);
top:50%;
left:50%;
z-index:1;
opacity:0;
}
}

//inputを全て消す
input[name="saya-button"] {
display: none;
}

//押したさやの色を変える
#button-1:checked ~ .saya--1 .saya__push,
#button-2:checked ~ .saya--2 .saya__push,
#button-3:checked ~ .saya--3 .saya__push {
opacity:1;
}

.saya-wrap.sayaの部分は さやのぼこぼこの部分で説明してる記述だな。

.saya__pushはさやを押したときに出現する楕円の記述だぞ。

checkedになったときに出現させたいので、opacity:0にして透明にしとくぞい。

ほんで、肝心の①さやを押したら〜の部分は、そのあとの記述で実現しているぞ。

何してるのか下で解説するぞい!


inputを画面から抹消

inputの部分は仕組みだけを利用したいので、display:noneして画面からは抹消してるぞ。


#id名:checked~を使う

いま、inputlabelはそれぞれbutton-1button-2button-3っていうIDで紐づいているよな。

で、labelをクリックしたらそれに対応しているinputにはcheckedが付与されるよな?

その状態を、#button-1:checkedのように指定することができるんじゃ!

また、~間接セレクタっていうやつで、兄弟関係にあれば間に別の要素が入っても指定ができるっつう便利セレクタじゃ。

つまり、#button-1:checked ~ .saya--1 .saya__pushは、

#button-1が選択されたとき、.saya--1の中の.saya__pushのopacity(透明度)が1になるていう指定をしてるんだぞ。




※ここで一個注意してほしいのは、

~の後に指定するのは、必ず同階層にある要素にしてねってことだぞ。

つまり急に#button-1:checked ~ .saya__pushとかは無理ってことだな。

【参考】間接セレクタ (E ~ F)


まめのアニメーションを作る

ここまで来たらあとちょっとだぞ!!!(記事書いてる自分に言い聞かせてる)

上の仕組みを利用して、

②さやをクリックしたらまめが飛び出すアニメーションを作成するぞ。


その前にまめを作る

まめ作ってなかった。まめのパーツはこんな感じのを組み合わせてつくってるぞい。

<div class="mame"></div>

%mame,.mame{

//まめ
background:#95D62C;
width:40px;
height:30px;
border-radius:20px / 15px;
z-index:-1;
position:absolute;
transform:translateX(-50%) translateY(-50%);
top:50%;
left:50%;
&:before{
//まめの上のちょん
content:"";
background:#75A724;
width:8px;
height:4px;
border-radius:100%;
position:absolute;
top:0;
left:16px;
}
&:after{
//まめの目
content:"・・";
letter-spacing: -8px;
color:#6E6E6E;
font-size:16px;
position:absolute;
top:0;
left:8px;
}
}

そいえば、さっきの.saya__pushの時にも使ってたんだが、

  position:absolute;

transform:translateX(-50%) translateY(-50%);
top:50%;
left:50%;

これをするだけで親要素の中央に配置することができるので非常に便利だぞ。

(アニメーションさせる前のまめは.saya--1.saya--3の中央にそれぞれ配置してるぞ。)

なんでこれで中央にいくの?って人は以下の記事がわかりやすいぞ!!!

【参考】CSSで要素を上下や左右から中央寄せする7つの方法

あと、.mameはさやの下から出てくるようにしたいので、z-index:-1にして隠してるぞ。


@keyframesでぽんっと出るまめ



↑こうなってほしい

さやに色を乗せたときと同じように、#button-1:checked ~.mameを指定していくぞ!

また、アニメーションは以下のような@keyframesを作成して、checkedになったときに発動するようにanimation:で指定をするぞ。

//まめを飛ばす

#button-1:checked ~ .saya--1 .mame,
#button-2:checked ~ .saya--2 .mame,
#button-3:checked ~ .saya--3 .mame {
animation: pon 0.2s ease-in-out forwards;
}

@keyframes pon {
//まめ飛び出しアニメーション
0% { transform:translate(-50%,-10px) rotate(8deg);}
10% { transform:translate(-50%,-10px) rotate(-8deg);}
20% { transform:translate(-50%,-30px) rotate(8deg);}
30% { transform:translate(-50%,-30px) rotate(-8deg);}
40% { transform:translate(-50%,-30px) rotate(8deg);}
50% { transform:translate(-50%,-30px) rotate(-8deg);}
99% { transform:translate(-50%,-30px);}
100% { transform:translate(-50%,-60px);}
}

今回はこんな感じになった。

@keyframestransformは、要素を左右に移動させたり、回転させたりするときに使うものよな。

今回は、まめがちょっとうずうず出るのを渋ってから、最終的にぽーんと飛び出す

っていうアニメーションにしたかったので、パーセンテージを区切って少しずつ動くようにしたぞい。

それぞれ指定の意味はこんな感じだぞ。



ちなみに毎回translateのX軸が-50%になってるのは、さっき.mameを中央寄せしたときに

transform:translateX(-50%) translateY(-50%);って記述を入れてて

そのtranslateXを維持するためだぞ。入れないと横にずれるんじゃ・・・。

99%まで、入り口付近にまめを置いといて

最後100%で一気に飛び出させることで、勢いを表現しているぞ!

一応アニメーションの指定の仕方も。

で、できた〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜✌︎('ω'✌︎ )


やってみて

無限にプチプチできて楽しいのう