#1 2020年8月にツイートしたTipsまとめ

16 min読了の目安(約15100字TECH技術記事
Likes126

2020 年 8 月にツイートした HTML/CSS/JavaScript のツイートまとめです。見出しをクリックするとツイート元に遷移するので、気に入ったらフォロー・ファボ・リツイートお願いします。

1. enterkeyhint属性

スマホキーボードのエンターキ表示を最適化でき、フォームが送信されたときの動作をあらかじめ伝えられます。

<input enterkeyhint="enter">
<input enterkeyhint="go">
<input enterkeyhint="done">
<input enterkeyhint="next">
<input enterkeyhint="previous">
<input enterkeyhint="search">
<input enterkeyhint="send">

各属性値を指定したときの表示は以下のようになります。

2. iOS Safariの文字サイズがデカくなるバグの修正

iOS Safari では、勝手に一部の文字サイズが大きくレンダリングされることがあります。それを防ぐにために、body に -webkit-text-size-adjust: 100%; を指定しておきます。

body {
  -webkit-text-size-adjust: 100%;
}

3. 属性セレクタのフラグ

属性セレクタで指定するとき、末尾に i フラグをつけると属性値が大文字小文字の区別なしに判定されるようになります。

<img src="image.jpg">
<img src="image.JPG">
img[src$=".jpg" i] { ... }

このようにすると、.jpg でも .JPG でも .jPg でも判定されるようになります。IEなど、対応していないブラウザには postcss-attribute-case-insensitive プラグインを使います。

4. メインコンテンツにスキップするリンク

キーボードや音声読み上げソフトユーザー向けに、メインコンテンツへスキップするリンクを用意しておくとよいです。キーボード操作や音声読み上げソフトだと Web サイトの一番上から順番にタブキーで移動するので、いきなり記事本文などのメインコンテンツを読みたい場合に不便です。

<!doctype html>
<html>
<head>...</head>
<body>

<a class="skip-link" href="#main" tabindex="0">メインコンテンツにスキップ</a>

...
...
...

<main id="main">
  ここはWebサイトのメインとなるコンテンツ部分です。
</main>

</body>
</html>

メインコンテンツへスキップする a 要素は <body> のすぐ後ろに配置します。

.skip-link:not(:focus) {
  position: absolute !important;
  margin: -1px !important;
  padding: 0 !important;
  width: 1px !important;
  height: 1px !important;
  white-space: nowrap !important;
  border: 0 !important;
  overflow: hidden !important;
  clip: rect(1px, 1px, 1px, 1px) !important;
  clip-path: inset(50%) !important;
}

:not(:focus) で、フォーカスされていないときはスキップリンクを隠しています。

5. Flexboxとテキストの省略を同時使用

Flexbox と text-overflow: ellipsis; を同時に使うテクニックです。

<div class="file">
  <div class="file-name">デザインカンプ_20200724_修正_修正済_追加修正_最終修正_追加修正2_再最終修正</div>
  <div class="file-ext">.xd</div>
</div>
.file {
  display: flex;
}
.file-name {
  min-width: 0;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}
.file-ext {
  flex-shrink: 0;
}

可変の .file-name には min-width: 0; を指定して Flex アイテムのはみ出しを防ぎ、.file-ext には画面幅を狭めたときに潰れないよう flex-shrink: 0; を指定しています。

6. 背景画像のちらつき防止

background-image プロパティで背景画像を :hover で切り替えるとき、以下の書き方だとホバーされるまで url('https://picsum.photos/id/124/500') は読み込まれません。

<div class="bg-image"></div>
.bg-image {
  width: 200px;
  height: 200px;
  background-position: center;
  background-size: cover;
  background-image: url('https://picsum.photos/id/85/500');
  background-repeat: no-repeat;
}
.bg-image:hover {
  background-image: url('https://picsum.photos/id/124/500');
}

そのため、ホバーされたときに初めて画像のロードが開始され、表示されるまでに時間がかかり、ちらつきが発生してしまいます。

.bg-image {
  width: 200px;
  height: 200px;
  background-position: center;
  background-size: cover, 0 0;
  background-image: url('https://picsum.photos/id/85/500'),
                    url('https://picsum.photos/id/124/500');
  background-repeat: no-repeat;
}
.bg-image:hover {
  background-size: 0 0, cover;
}

そこで、初期段階でホバー後に表示する画像も読み込ませておき、background-size: 0 0; を指定して隠しておきます。

ホバーされたら、background-size: cover; にして、逆に最初に表示していた画像は background-size: 0 0; で隠すことで背景画像の切り替えができます。

今回はホバーの例ですが、JavaScriptを使った背景画像の切り替えのときにも活用できます。

7. インライン要素のまま改行

インライン要素を維持しつつ、ブロックレベル要素のように改行させたい場合に使えるテクニックです。

<span>インライン要素</span>
<span>インライン要素</span>
<span>インライン要素</span>
...
span::after {
  content: '\a';
  white-space: pre;
}

擬似要素 ::after で改行コード u+000a の content: '\a'; を指定し、white-space: pre; を指定することで改行コードがそのままレンダリングされるようにしています。

8. 絵文字をアイコンとして利用

絵文字の文字色を透明にして、text-shadow プロパティで影を同じ場所に表示させることで、絵文字のシルエットをアイコンとして利用できます。

<span class="icon" aria-hidden="true">💚</span>
.icon {
  color: transparent;
  font-size: 100px;
  text-shadow: 0 0 0 #fc2e67;
}

9. 上下左右中央揃え

最近は、上下左右中央揃えをたった 2 行でできるようになっています。

.centering {
  display: grid;
  place-items: center;
}

place-items プロパティに対応していないブラウザには、postcss-place を使えば大丈夫です。

.centering {
  display: flex;
  align-items: center;
  justify-content: center;
}

そもそも、display: grid; に対応していないブラウザ向けに制作する場合は従来通りの display: flex; を使った方法を用います。

10. overflowプロパティの指定

ほとんどの場合、overflow: scroll; ではなく overflow: auto; を指定した方が自然です。overflow: scroll; だとスクロールがないときでもスクロールバーが表示されてしまいます。

画像は Windows の例ですが、MacOS でも常にスクロールバーを表示させているユーザーは同じ状態になります。

11. ページ内リンクのアニメーション

ページ内リンクをクリックしたときに移動先をハイライトするテクニックです。

<a href="#jump">ジャンプする</a>

...
...
...

<div id="jump">ジャンプ先です!</div>
html {
  scroll-behavior: smooth;
}
#jump:target {
  animation: highlight 2.4s ease-in-out;
}
@keyframes highlight {
  0% {
    background-color: yellow;
  }
  100% {
    background-color: rgba(255, 255, 255, 0);
  }
}

:target 擬似クラスを使って、ページ内リンクがクリックされたときにアニメーションされるようにしています。html 要素には scroll-behavior: smooth;` を指定してスムーススクロールされるようにしています。

12. display: none;とダウンロード

display: none; でメディアを隠しても、コンテンツ自体はバックグラウンドでダウンロードされます。

img {
  display: none;
}

なので、display: none; でレスポンシブ画像を隠すのではなく、picture 要素と source 要素の media 属性を使ってその画面幅で必要な画像のみダウンロードされるようにします。

動画の場合は video 要素を使いますが、source 要素が media 属性に対応していないため、JavaScript を使って切り替える必要があります。

13. 折りたたみスマホのメディア特性

Microsoft が折りたたみスマホ向けのメディア特性の仕様を公開しました。

@media (screen-spanning: single-fold-vertical) {
  /* Figure1 折りたたみスマホの画面が横に2つ並んだ状態 */
}
@media (screen-spanning: single-fold-horizontal) {
  /* Figure2 折りたたみスマホの画面が縦に2つ並んだ状態 */
}

14. アスペクト比の固定

CSS で要素のアスペクト比を指定したいときは aspect-ratio プロパティが使えます。値は <横> / <縦> というように指定し、16 / 9 なら 16:9 のアスペクト比になります。

.box {
  aspect-ratio: 16 / 9;
}

対応ブラウザを見ると、ほとんどのブラウザが対応していないので postcss-aspect-ratio-polyfill を作りました。このプラグインを使えばすべてのブラウザで動くプロパティに変換されます。

15. CSS Color Module Level 5

CSS Color Module Level 5 では新たに色に関する関数が追加される予定です。

.selector {
  /*
    色の混合
    赤色60%と青色40%が混合される
  */
  color: color-mix(red 60%, blue);
  /*
    コントラスト比が高い色を算出
    1番目の引数wheatとの輝度コントラスト比が最も高いsiennaが選ばれる
  */
  color: color-contrast(wheat vs tan, sienna);
  /*
    色の調整
    赤色の明度を20%まで抑制する
  */
  color: color-adjust(red lightness -20%);
}

16. CSSの単位

以前は px よりも rem 単位を推奨していましたが、今は全部 px 単位で問題ないと思っています。理由は em と rem 関連のバグが非常に多いからです。

海外では px よりも em や rem 単位を推奨する感じが非常に強いです。

結局のところ、全ブラウザが文字サイズだけ調整できる機能を実装すればこの問題は解決するのですが、今のところ Firefox と Safari しか実装していません。

17. 配列の重複を削除

new Set() でユニークなオブジェクトを生成し、スプレッド演算子 ... で配列に展開することで、配列の重複を削除できます。

const array = [1, 2, 3, 3, 4, 5, 5]
const uniq = [...new Set(array)]
// => [1, 2, 3, 4, 5]

18. 特定の要素以外を判定

特定の要素以外がクリックされたときを判定するときは .closest() を使うのが便利です。

document.addEventListener('click', event => {
  if (!event.target.closest('.element')) {
    // .element以外がクリックされたとき
  }
})

モーダルの外側をクリックしたら閉じる処理やドロップダウンメニューの外側をクリックしたら閉じる処理など、色々応用できます。

import 'mdn-polyfills/Element.prototype.closest'

.closest() に対応していないブラウザには mdn-polyfills を使います。

19. 文字列の比較

一見、同じに見える文字列でも === で判定すると false が返ってくることがあります。

console.log('café' === 'café')
// => false

それぞれの文字列を Unicode で表すと、caf\u00E9 と cafe\u0301 になります。2 つめの文字列が e + アクセント記号 \u0301 となっており、Unicode 上等しくないため false が返ってきます。

console.log('café'.normalize() === 'café'.normalize())

そこで、String.normalize() 関数を使って文字列を正規化することで正しく判定されるようになります。

20. IEの判定

IE の判定にユーザーエージェントを使うと、将来的な仕様変更により壊れる可能性があります。Chrome ではすでにユーザーエージェントの廃止予定があります。

const isIE = document.documentMode

if (isIE) {
  // IEだけに適用されるコード
}

そこで、機能による判定である Feature Detection を使うと安全です。IE には独自実装として document.documentMode があり、5〜11 までのバージョン番号を返し、それ以外のブラウザでは undefined となります。

document.documentMode を使った判定方法は jQuery や AngularJS でも使われており、信頼性が高い方法といえます。

21. 電波状況の判定

navigator.connection を使うと電波状況が悪くなったときを検知できます。

if (navigator.connection) {
  navigator.connection.addEventListener('change', () => {
    const {rtt, effectiveType: ect} = navigator.connection

    if (rtt > 500 || ect.includes('2g')) {
      /* 地下鉄やトンネル内など一時的に電波状況が2Gレベルまで弱くなったとき */
    }
  })
}

22. mdn-polyfills

mdn-polyfills は IE や Edge でサポートされていない関数などをまとめた Polyfill ライブラリです。読み込みたいモジュールだけインポートすればいいので、扱いやすいです。

23. mailgo

mailgo は <a href="mailto:"> や <a href="tel:"> のリンクをクリックするとモーダルが開き、Gmail で開いたり単にコピーしたり選択できるようにするライブラリです。

24. Get Waves

Get Waves は SVG のおしゃれな波を生成できるオンラインジェネレーターです。

25. SVGOMG

SVGOMG は SVG の圧縮を細かく設定できるオンラインジェネレーターです。

26. wrap-svg

wrap-svg は SVG を自由に歪めたりしておしゃれにできるオンラインジェネレーターです。

27. Coolors

Coolors は配色のランダム生成や写真から配色を生成、色覚シミュレーション、グラデーション生成まで色々できるオンラインジェネレーターです。

28. gitignore.io

gitignore.io は環境に応じた .gitignore ファイルを生成してくれるオンラインジェネレーターです。

29. Whitespace to copy and paste

Whitespace to copy and paste は色んな種類のホワイトスペース文字をコピペできる Web サイトです。

30. indent-rainbowとTrailing Spaces

VSCode の拡張機能、インデント部分に色をつけてくれる indent-rainbow と行末の余分なスペースをハイライトしてくれる Trailing Spaces を入れると見やすくなるのでおすすめです。

31. Bracket Pair Colorizer 2

VSCode の拡張機能 Bracket Pair Colorizer 2 はかっこを自動で色分けしてくれます。

32. Bootstrap Icons

Bootstrap Icons は Bootstrap 製の 1000 種類を超えるアイコンライブラリです。

33. heroicons

heroicons は Tailwind 製の 200 種類を超えるアイコンライブラリです。

34. Forge Icons

Forge Icons は 300 種類を超えるアイコンライブラリです。

35. System UIcons

System UIcons は 200 種類を超えるシステム系のアイコンライブラリです。

36. Generated Photos

Generated Photos は AI による自動生成の著作権フリーで 200 万種類を超える顔画像を配布している Web サイトです。

37. DevToolsのスクリーンショット

Chrome 86 から DevTools の要素上で右クリックすると、Capture node screenshot という項目が追加されています。これまではページ全体のみでしたが、要素ごとにスクリーンショットを撮ることができるようになりました。

38. ユーザーエージェントの仕様変更

この記事 によると、User-Agent は廃止されて User-Agent Client Hints に変更されるようです。そのため、ユーザーエージェントを使うのはやめておいた方がいいかもしれません。