よくJavaScriptで実装されるものを
HTML・CSSで実装してみた

吉川雅彦

このLTでやること

今日のLTの目的

JS以外の手段を知る。

IE11〜、iOS Safari 9.2〜、Androidブラウザ4.4〜でだいたい動くものを紹介(ベンダープレフィックスが必要な場合も)。

今日話さないこと

「JS」「HTML・CSS」どちらで実装すべきか(プロジェクトによる)

JSを使わないときって?

SEOとして

描画速度向上のため

どうしてもJS使っちゃダメな環境

デメリット

かえって複雑になる場合がある

古いブラウザ・マイナーブラウザを切り捨てないといけない場合がある

やってみた

バルーン表示

hoverでバルーン表示
バルーンの説明

ポイント

「:hover」擬似クラス。トリガーになる要素の子要素などのdisplayプロパティの値を変える。

クリックで他の要素のデザインを変更

check

ポイント

CSSの「:checked」擬似クラス。

デメリット

タブキー移動に対応していない。

高さが文字に合わせて可変する入力フォーム

<div class="variable-area" contenteditable="true"></div>

ポイント

「contenteditable="true"」

デメリット

送信ボタン押下時に値を渡せないため、結局JSが必要。

クレジットカード入力時の区切りのスペースを入れる

ポイント

等幅フォントと「column-count」プロパティの組み合わせ。

テキストフォームで補完

<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のバリデーション

必須項目
数字とハイフンのみ
<input required="required">
<input pattern="^[-0-9]+$">

requiredなどを入れるだけでバリデートしてくれるようになった。

項目を入力したら1つ増やしたい

ポイント

「contenteditable="true"」と「:not(:empty)」の組み合わせ。

デメリット

本当の意味で要素を増やすのは無理なので、あらかじめ用意して「display:none」で隠しておく必要がある。

datepicker的なもの(カレンダー)を実装する

<input type="date">
PCは未対応が多い。Firefox(PC)は、アドレス欄に「about:config」から「dom.forms.datetime」フラグONでそれっぽいものが。

アコーディオンメニュー

    • 子メニュー1-1
    • 子メニュー1-2
    • 子メニュー2-1
    • 子メニュー2-2
    • 子メニュー2-3
    • 子メニュー2-4

ポイント

「:checked」擬似要素。

Tweetボタン

ポイント

Facebook等も同様に。

デメリット

公式の方法ではないため、仕様が変更された場合に対応しなければならない。

カード型デザインで、高さを列の一番高いものに揃える

テスト文章テスト文章
テスト文章
テスト文章
テスト文章
テスト文章
テスト文章
テスト文章
テスト文章

ポイント

「display: flex」「flex-wrap: wrap」。

高さ可変のブロックに、開閉アニメーションをつける

吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。
『吾輩は猫である』

ポイント

max-heightプロパティに、「ビューポート」基準の値を設定。

デメリット

アニメーションが思いどおりにいかない。

ブロック内にきっちり画像を収める

画像
画像

ポイント

画像のwidthとheightをautoにしつつ、max-heightとmax-widthに上限を設ける。
IE8にも対応。
「background-size: contain」を背景ではなくimg要素にしたいとき。

ブロック内にきっちり画像を収める2

画像
画像

ポイント

新しめのプロパティ「object-fit: contain」を指定。
「object-fit: cover」で隙間なく広がる。

スライダー

1
2
3

ポイント

ラジオボタンの:checked による、animationの切り替え。

モーダルウィンドウ

ポイント

チェックボックスの「:checked」擬似クラス。

プレゼンスライド

ポイント

「:target」擬似クラス。ブラウザの戻る機能で戻れる。
今回のスライドはJSは使っていません。

デメリット

デメリットしかない。

HTML・CSSのみで実装する
デメリット

保守性の低下

現在のCSSでは、トリガーになる要素の「子要素・子孫要素」や、トリガー要素以降の「兄弟要素(とその子要素・子孫要素)」にしか、変化を適用できない。

:hover、:checked、:target、:focus、:active……。

トリガーになる要素をdivで囲ってしまい、テスト時に動作に気づかずリリース……、なんてことも。

結局JSを使う場合も

編集可能にする「contenteditable属性」を使うと、結局submit時に値を取れないのでJSで取得する必要がある。また、けっこう使いづらい。

ちなみに、Twitterの投稿フォームはこれになっている。

アクセシビリティやユーザビリティの低下

チェックボックスやラジオボタンなど、「display:none」で消してしまうと、タブキーで移動できない。

トリガーのためだけにチェックボックスを用意すると、論理構造としておかしなことになる。セマンティックじゃない(JSを使えば解決するわけでもないけど)。