💬

No.11 2021年7,8月にツイートしたHTML/CSS/JavaScriptのTipsまとめ

2022/01/14に公開約14,300字

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

1. SVGでパスに沿ってテキストを配置

Illustrator でいい感じに波状のパスを描きます。パスを選択した状態で [オブジェクト] → [アートボード] → [選択オブジェクトに合わせる] でパスの大きさぴったりにアートボードをリサイズします。

[ファイル] → [書き出し] → [書き出し形式] でファイル形式を SVG で書き出します。ポップアップメニューが出てくるので、[コードを表示] をクリックして SVG コードを表示します。viewBoxd 属性の値をコピーしておきます。

あとは以下のコードの viewBoxd 属性にそのまま指定するだけです。

<svg viewBox="0 0 410.06 101">
  <path id="curved-text" d="M.05,64.48c61.58,6.39,58.65,34.58,135.43,36C244,102.47,295.36,2.71,410.05.5" stroke="none" fill="none"/>
  <text>
    <textPath href="#curved-text">あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら</textPath>
  </text>
</svg>

2. 雑誌のように1文字目を大きくする

::first-letter で 1 文字目のスタイルを調整できます。

p:first-child::first-letter {
  float: left;
  line-height: 1;
  font-size: 3em;
}

3. drop-shadow()

drop-shadow() を使うと PNG や SVG などの背景透過画像に対して影をつけられます。

svg {
  filter: drop-shadow(3px 5px 10px rgba(101, 119, 134, .7));
}

4. fit-content

width プロパティに fit-content 値を指定すると、ブロックレベル要素を維持しつつ、inline-block のようにコンテンツに合わせて幅が変動します。

.box {
  width: -moz-fit-content;
  width: fit-content;
}

5. <ul> 要素のスタイルをリセットするときの小技

<ul> 要素自体をリセットするのではなく、クラス指定があるときのみ余白やリストマークを消すことで、できる限りデフォルトのスタイルを残すリセット方法です。一見すると良さそうですが問題があります。

ul[class] {
  margin: 0;
  padding: 0;
  list-style: none;
}

.list などの単一のクラス名でスタイルの上書きをしようとすると詳細度の関係で上書きできません。

.list {
  list-style-type: square;
}

そのため、ul.list のように詳細度を上げる必要が出てきます。

ul.list {
  list-style-type: square;
}

:where 擬似クラスを使えば、引数のセレクタの詳細度を 0 にできるので、詳細度を合わせて上書きできるようになります。

/* :where()内は詳細度が0になる */
ul:where([class]) {
  margin: 0;
  padding: 0;
  list-style: none;
}
/* これなら上書きできる */
.list {
  list-style-type: square;
}

6. たった1行で連番

連番であれば counter-increment プロパティで独自のカウンターを定義しなくても list-item 値を使うことでシンプルに書けます。

<ol>
  <li>ここにテキストが入ります。</li>
  <li>
    ここにテキストが入ります。
    <ol>
      <li>ここにテキストが入ります。</li>
      <li>ここにテキストが入ります。</li>
    </ol>
  </li>
  <li>ここにテキストが入ります。</li>
</ol>
li::marker {
  content: '(' counters(list-item, '.') ')';
}

7. スクロールバーによるLayout Shiftを防ぐ

クラシックスクロールバーは Windows などのボックス内に場所をとるスクロールバーで、オーバーレイスクロールバーは MacOS や iOS などのボックス内にオーバーレイで表示されるスクロールバーです。

クラシックスクロールバーの Windows では、要素内のテキストが動的に増えたときにスクロールの幅分、要素幅が減るため Layout Shift が起きてしまいます。

scrollbar-gutter プロパティに stable を指定すると、コンテンツ量が少ない場合でもスクロールバーの幅分のスペースが確保され、コンテンツ量が増えたときの Layout Shift を回避できます。記事執筆時点では Chrome のみが対応しています。

.box {
  scrollbar-gutter: stable;
}

8. ダブルタップによる拡大を防ぐ

iOS Safari ではダブルタップすると画面が拡大されてしまいます。例えば、ボタンなどを連打してしまったときにも画面が拡大されてしまうのは困ります。

button {
  touch-action: manipulation;
}

9. CSS Module Scripts

CSS Module Scripts を使うことで同じ CSS ファイルが別の場所から読み込まれても、取得・インスタンス化・解析は 1 回しか行われません。また、モジュールは CORS で取得されて厳密な MIME タイプチェックが行われます。Chrome 93 から使えます。

<script type="module">

import sheet from './css-import.css' assert {type: 'css'}

document.adoptedStyleSheets = [sheet]

</script>

10. focus() のオプション

preventScroll オプションを true にすると、フォーカスする要素が画面外にあってもスクロールしなくなります。対応していないブラウザには focus-options-polyfill を使えば対応できます。

<button>スクロールせずにフォーカスを当てる</button>
<input type="text">
document.querySelector('button').addEventListener('click', () => {
  document.querySelector('input').focus({preventScroll: true})
})

11. Promise エラー処理の違い

Promise のエラーハンドリングには 2 種類の方法があります。

Promise.resolve('Valid!!')
  .then(/* 成功時の処理 */, /* 失敗時の処理 */)
Promise.resolve('Valid!!')
  .then(/* 成功時の処理 */)
  .catch(/* 失敗時の処理 */)

違いは Promise.reject() したときに現れます。Promise.then().catch() の方は .then() 内でのエラーを .catch() 内で取得できます。

Promise.resolve('Valid!!')
  .then(value => {
    return Promise.reject('Invalid!!')
  }, error => {
    // 何も出力されない
    console.log(error)
  })
Promise.resolve('Valid!!')
  .then(value => {
    return Promise.reject('Invalid!!')
  })
  .catch(error => {
    // Promise.reject()した値のInvalid!!が出力される
    console.log(error)
  })

具体的な使い道として、GitHub のリポジトリ一覧を取得する処理を書いてみました。

fetch('https://api.github.com/users/takamoso/repos')
  .then(async res => {
    const repos = await res.json()
    
    if (repos.length === 0) {
      return Promise.reject(new Error('No Repo!'))
    }

    return repos
  })
  .catch(error => {
    // GitHubのリポジトリが1つもない場合はここでエラーを受け取れる
    console.log(error)
  })

12. 論理代入演算子

x ||= yxfalsy な値のときにのみ、xy を代入します。

論理和代入演算子||=
const user = {
  id: 7,
  name: '',
}

user.id ||= 1
console.log(user.id)  // 7

user.name ||= 'Bob'
console.log(user.name)  // Bob

x &&= yxtruthy な値のときにのみ、xy を代入します。

論理積代入演算子&&=
let a = 1
let b = 0

a &&= 2
console.log(a)  // 2

b &&= 2
console.log(b)  // 0

x ??= yxnullishnull または undefined)な値のときにのみ、xy を代入します。

null合体代入演算子??=
const user = {
  id: 7,
}

user.id ??= 1
console.log(user.id)  // 7

user.name ??= 'Bob'
console.log(user.name)  // Bob

13. Promise.any()

Promise.any() は引数のうち、最初に成功した Promise を返します。

const promiseError = new Promise((resolve, reject) => reject('失敗'))
const promiseSlow = new Promise((resolve, reject) => setTimeout(resolve, 700, '0.7秒後に成功'))
const promiseFast = new Promise((resolve, reject) => setTimeout(resolve, 200, '0.2秒後に成功'))

Promise.any([
  promiseError,
  promiseSlow,
  promiseFast,
]).then(first => {
  console.log(first)  // 0.2秒後に成功
}).catch(error => {
  // すべてのPromiseが失敗したとき
})

先に失敗した Promise があっても、成功した Promise が 1 つでもあれば解決します。

14. Object.hasOwn()

Object.hasOwn()Object.prototype.hasOwnProperty.call() のエイリアスです。オブジェクトが特定のプロパティを持つかどうかを判定します。

// オブジェクトが指定したプロパティを持っているかどうか
console.log(Object.hasOwn({prop: 42}, 'prop'))  // => true

// Object.hasOwnはObject.prototype.hasOwnProperty.callのエイリアス
console.log(Object.prototype.hasOwnProperty.call({prop: 42}, 'prop'))  // => true

15. 配列のシャッフル

Fisher-Yates アルゴリズムを使ってシャッフルを実装しています。

const shuffle = array => {
  // 配列をコピー
  const result = [...array]

  for (let i = result.length - 1; i > 0; i--) {
    // ランダムなインデックス
    const j = Math.floor(Math.random() * (i + 1))

    // 入れ替え
    ;[result[i], result[j]] = [result[j], result[i]]
  }

  return result
}

const array = [1, 2, 3, 4, 5, 6, 7, 8, 9]

console.log(shuffle(array))

16. The New CSS Reset

The New CSS Reset はまったく新しいリセット CSS です。

https://github.com/elad2412/the-new-css-reset

17. viewerjs

多機能なイメージビューワーライブラリです。

https://github.com/fengyuanchen/viewerjs

18. cropperjs

画像をトリミング編集できるライブラリです。

https://github.com/fengyuanchen/cropperjs

19. milkdown

プラグインで機能拡張もできる WYSIWYG マークダウンエディタのライブラリです。

https://github.com/Saul-Mirone/milkdown

20. slate

Medium や Google ドキュメントのようなリッチテキストエディタを実装できるライブラリです。

https://github.com/ianstormtaylor/slate

21. drift

Amazon のような商品画像にホバーすると拡大表示してくれるライブラリです。

https://github.com/imgix/drift

22. eva.js

フロントエンド向けのゲームエンジンライブラリです。

https://github.com/eva-engine/eva.js

23. svgbob

アスキーアートなどのダイアグラムを SVG に変換してくれるライブラリです。

https://github.com/ivanceras/svgbob

24. wavesurfer.js

音声の波形を Canvas 上に描画できるライブラリです。

https://github.com/katspaugh/wavesurfer.js

25. blurhash

美しいプレースホルダー画像をハッシュ値から生成・復元できるライブラリです。

https://github.com/woltapp/blurhash

26. spacers

デザインカンプのように Web ページ上の要素間の余白を調整できるライブラリです。

https://github.com/actuallyakash/spacers

27. imaskjs

<input> 要素の入力値を特定の文字のみに制限できるライブラリです。

https://github.com/uNmAnNeR/imaskjs

28. flv.js

Flash なしで FLV 動画を再生できるようにするライブラリです。

https://github.com/bilibili/flv.js

29. fzf-for-js

あいまい検索を実装できるライブラリです。

https://github.com/ajitid/fzf-for-js

30. color

色形式の変換と色の変化を適用できるライブラリです。

https://github.com/Qix-/color

31. html-to-image

HTML の DOM ノードを PNG や SVG などの画像として出力できるライブラリです。

https://github.com/bubkoo/html-to-image

32. filesize.js

ファイルサイズをわかりやすく単位つきに変換してくれるライブラリです。

https://github.com/avoidwork/filesize.js

33. zx

シェルスクリプトを Node.js で扱えるライブラリです。

https://github.com/google/zx

34. pdfmake

クライアントサイドとサーバーサイド両方で PDF を生成できるライブラリです。

https://github.com/bpampuch/pdfmake

35. js-cookie

ブラウザの Cookie を簡単に扱えるライブラリです。

https://github.com/js-cookie/js-cookie

36. sift.js

MongoDB 風のクエリを扱えるライブラリです。

https://github.com/crcn/sift.js

37. color-thief

画像からカラーパレットを生成できるライブラリです。

https://github.com/lokesh/color-thief

38. hyperformula

Excel のような表計算ができるライブラリです。

https://github.com/handsontable/hyperformula

39. fast-deep-equal

高速に 2 つのオブジェクトや配列が一致しているかどうかを判定できるライブラリです。

https://github.com/epoberezkin/fast-deep-equal

40. shiki

美しいシンタックスコードハイライターを実装できるライブラリです。SVG 形式で書き出すこともできるようです。

https://github.com/shikijs/shiki

41. pnpm

npm で依存モジュールのインストールを 1 箇所にまとめて、個別のプロジェクトはシンボリックリンクを用いることで軽量化と高速化を実現した Node.js ライブラリです。

https://github.com/pnpm/pnpm

42. AVPress

オンライン上で動画圧縮と書き出しができるオンラインツールです。

https://avpress.zaps.dev/

43. PhotoRoom Background Remover

画像の背景を自動で削除してくれるオンラインジェネレーターです。API もあり、類似サービスよりも低価格で利用できます。

https://www.photoroom.com/background-remover/

44. Blobbb

SVG 形式の Blob 画像を生成できるオンラインジェネレーターです。

https://www.blobbb.fun/

45. Unicode Arrows

Unicode の矢印だけを集めたサイトです。

https://unicodearrows.com/

46. flag-icons

世界の国旗の SVG 画像集です。

https://github.com/lipis/flag-icons

47. SVG Gobbler

Web サイト上の SVG 画像を編集やカスタマイズ、ダウンロードできるブラウザ拡張機能です。

https://www.svggobbler.com/

No.10 ← |


今すぐ使えるCSSレシピブック

Discussion

ログインするとコメントできます