JavaScriptをあまり使いたくない、使えない。
速度の面やSEOとして、CSSで実装したい。
そんな方のために、JavaScriptで実装されがちなものを、HTML・CSSのみで実装してTipsにしてみました。
IE11〜、iOS Safari 9.2〜、Androidブラウザ4.4〜でだいたい動きます(ベンダープレフィックスが必要な場合も)。
デメリットもあるので、合わせて確認してみてください。
バルーン表示
demo
HTML・CSS
<div class="hover-balloon">hoverでバルーン表示<div class="hover-balloon__text">バルーンの説明</div></div>
クリックで他の要素のデザインを変更
demo
ここの要素の色が変わる
HTML・CSS
<label for="check">click1</label> <label for="check">click2</label> <input type="checkbox" id="check"><span>ここの要素の色が変わる</span>
ポイント
CSSの「:checked」擬似クラス。
デメリット
タブキー移動に対応していない。これ系は、そのまま使うと全部タブキー移動に対応していないので注意してください。
高さが文字に合わせて可変する入力フォーム
demo
HTML・CSS
<div class="variable-area" contenteditable="true"></div>
ポイント
「contenteditable=”true”」
デメリット
送信ボタン押下時に値を渡せないため、結局JavaScriptが必要。これを使うものはぜんぶそんな感じです。
クレジットカード入力時の区切りのスペースを入れる
demo
HTML・CSS
<div class="credit-card" contenteditable="true"></div>
ポイント
等幅フォントと「column-count」プロパティ(段組み)の組み合わせ。
テキストフォームで補完
demo
HTML
<input name="yourname" autocomplete="on" list="yourname"> <datalist id="yourname"> <option value="yoshikawa"> <option value="yoshida"> <option value="yoneda"> <option value="yokoyama"> <option value="yamada"> </datalist>
ポイント
datalist要素。
デメリット
Safari、iOS Safariなど非対応。
Formのバリデーション
demo
HTML
<input required="required"> <input pattern="^[-0-9]+$">
requiredなどを入れるだけでバリデートしてくれるようになりました。HTML5になって、「type=”tel”」や「type=”email”」やらいろいろ追加されました。
項目を入力したら1つ増やしたい
demo
HTML・CSS
<div class="item" contenteditable="true"></div> <div class="item" contenteditable="true"></div> <div class="item" contenteditable="true"></div> <div class="item" contenteditable="true"></div> <div class="item" contenteditable="true"></div> <div class="item" contenteditable="true"></div>
ポイント
「contenteditable=”true”」と「:not(:empty)」の組み合わせ。
デメリット
本当の意味で要素を増やすのは無理なので、あらかじめ用意して「display:none」で隠しておく必要があります。
datepicker的なもの(カレンダー)を実装する
demo
HTML
<input type="date">
アコーディオンメニュー
demo
-
- 子メニュー1-1
- 子メニュー1-2
-
- 子メニュー2-1
- 子メニュー2-2
- 子メニュー2-3
- 子メニュー2-4
HTML・CSS
<ul class="accordion"> <li> <input type="checkbox" id="accordion-menu-1"><label for="accordion-menu-1">メニュー1</label> <ul> <li>子メニュー1-1</li> <li>子メニュー1-2</li> </ul> </li> <li> <input type="checkbox" id="accordion-menu-2"><label for="accordion-menu-2">メニュー2</label> <ul> <li>子メニュー2-1</li> <li>子メニュー2-2</li> <li>子メニュー2-3</li> <li>子メニュー2-4</li> </ul> </li> </ul>
ポイント
「:checked」擬似要素。
Tweetボタン
カード型デザインで、高さを列の一番高いものに揃える
demo
CSS
ポイント
「display: flex」「flex-wrap: wrap」。
高さ可変のブロックに、開閉アニメーションをつける
demo
hoverで開閉。
吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。
『吾輩は猫である』
CSS
ポイント
max-heightプロパティに、「ビューポート」基準の値を設定。
デメリット
アニメーションが思いどおりにいかない。
ブロック内にきっちり画像を収める
demo
CSS
ポイント
画像のwidthとheightをautoにしつつ、max-heightとmax-widthに上限を設ける。
IE8にも対応。
「background-size: contain」を背景ではなくimg要素にしたいとき。
ブロック内にきっちり画像を収める2
demo
CSS
ポイント
新しめのプロパティ「object-fit: contain」を指定。
「object-fit: cover」で隙間なく広がる。
スライダー
demo
HTML・CSS
<input type="radio" name="slider-radio" class="slider-radio" id="check-slider-1" checked="checked"> <input type="radio" name="slider-radio" class="slider-radio" id="check-slider-2"> <input type="radio" name="slider-radio" class="slider-radio" id="check-slider-3"> <div class="slider-inner"> <div class="slider slider-1"><label class="slider-label" for="check-slider-3"><</label><span>1</span><label class="slider-label" for="check-slider-2">></label></div> <div class="slider slider-2"><label class="slider-label" for="check-slider-1"><</label><span>2</span><label class="slider-label" for="check-slider-3">></label></div> <div class="slider slider-3"><label class="slider-label" for="check-slider-2"><</label><span>3</span><label class="slider-label" for="check-slider-1">></label></div> </div>
ポイント
ラジオボタンの:checked による、animationの切り替え。
デメリット
スマホで、2回連続同じスライドに行くときに不安定。
モーダルウィンドウ(ポップアップウィンドウ)
demo
HTML・CSS
<label for="modal-check">Open</label><input type="checkbox" id="modal-check"><span class="modal"><label for="modal-check">Close</label></span>
ポイント
チェックボックスの「:checked」擬似クラス。
プレゼンスライド
ポイント
「:target」擬似クラス。ブラウザの戻る機能で戻れる。
今回のスライドはJavaScriptは使っていません。
デメリット
デメリットしかない。ちゃんとJavaScriptで楽しましょう。
HTML・CSSのみで実装するデメリット
保守性の低下
現在のCSSでは、トリガーになる(状態が変化する)要素の「子要素・子孫要素」や、トリガー要素以降の「兄弟要素(とその子要素・子孫要素)」にしか、変化を適用できない。
:hover、:checked、:target、:focus、:active……。
トリガーになる要素をdivで囲ってしまい、テスト時に動作に気づかずリリース……、なんてことも。
結局JSを使う場合も
編集可能にする「contenteditable属性」を使うと、結局submit時に値を取れないのでJavaScriptで取得する必要がある。また、けっこう使いづらい(コピペをするとスタイルが反映されてしまったりなど)。
ちなみに、Twitterの投稿フォームはこれで実装されています。
アクセシビリティやユーザビリティの低下
チェックボックスやラジオボタンなど、「display:none」で消してしまうと、タブキーで移動できない。
トリガーのためだけにチェックボックスを用意すると、論理構造としておかしなことになる。セマンティックじゃない(JavaScriptを使えば解決するわけでもないけど)。
使いどころ
実際にどういうときに使えばいいのか、というところがあると思うので列挙してみました。
- ブログに投稿するのにJavaScriptが使えない
- クライアントにJavaScriptを使わないように言われている
- AMP対応でJavaScriptが使えない(使える擬似クラスなど限られていますが)
- 描画速度を優先させたい(必ずしも速くなるわけではないけど、だいたい速い)
- SEO対策で(一概にCSSのみで実装すればいいといえないですが)
- ユーザーがスマホ中心なため、非力なスマホでもインタラクションを加えたい
まとめ
JavaScriptとHTML・CSS、どちらで実装するかは、プロジェクトによるかなと思います。
また、Hack的な使い方多いため、
メリット・デメリットをしっかり理解して実装しましょう。
ポイント
「:hover」擬似クラス。トリガーになる要素の子要素などのdisplayプロパティの値を変える。