No.11 2021年7,8月にツイートしたHTML/CSS/JavaScriptのTipsまとめ
2021 年 7, 8 月にツイートした HTML/CSS/JavaScript のツイートまとめです。見出しをクリックするとツイート元に遷移するので、気に入ったらフォロー・ファボ・リツイートお願いします。
SVGでパスに沿ってテキストを配置
1.Illustrator でいい感じに波状のパスを描きます。パスを選択した状態で [オブジェクト] → [アートボード] → [選択オブジェクトに合わせる] でパスの大きさぴったりにアートボードをリサイズします。
[ファイル] → [書き出し] → [書き出し形式] でファイル形式を SVG で書き出します。ポップアップメニューが出てくるので、[コードを表示] をクリックして SVG コードを表示します。viewBox
と d
属性の値をコピーしておきます。
あとは以下のコードの viewBox
と d
属性にそのまま指定するだけです。
<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>
雑誌のように1文字目を大きくする
2.::first-letter
で 1 文字目のスタイルを調整できます。
p:first-child::first-letter {
float: left;
line-height: 1;
font-size: 3em;
}
drop-shadow()
3. drop-shadow()
を使うと PNG や SVG などの背景透過画像に対して影をつけられます。
svg {
filter: drop-shadow(3px 5px 10px rgba(101, 119, 134, .7));
}
fit-content
4. width
プロパティに fit-content
値を指定すると、ブロックレベル要素を維持しつつ、inline-block
のようにコンテンツに合わせて幅が変動します。
.box {
width: -moz-fit-content;
width: fit-content;
}
<ul>
要素のスタイルをリセットするときの小技
5. <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;
}
たった1行で連番
6.連番であれば counter-increment
プロパティで独自のカウンターを定義しなくても list-item
値を使うことでシンプルに書けます。
<ol>
<li>ここにテキストが入ります。</li>
<li>
ここにテキストが入ります。
<ol>
<li>ここにテキストが入ります。</li>
<li>ここにテキストが入ります。</li>
</ol>
</li>
<li>ここにテキストが入ります。</li>
</ol>
li::marker {
content: '(' counters(list-item, '.') ')';
}
スクロールバーによるLayout Shiftを防ぐ
7.クラシックスクロールバーは Windows などのボックス内に場所をとるスクロールバーで、オーバーレイスクロールバーは MacOS や iOS などのボックス内にオーバーレイで表示されるスクロールバーです。
クラシックスクロールバーの Windows では、要素内のテキストが動的に増えたときにスクロールの幅分、要素幅が減るため Layout Shift が起きてしまいます。
scrollbar-gutter
プロパティに stable
を指定すると、コンテンツ量が少ない場合でもスクロールバーの幅分のスペースが確保され、コンテンツ量が増えたときの Layout Shift を回避できます。記事執筆時点では Chrome のみが対応しています。
.box {
scrollbar-gutter: stable;
}
ダブルタップによる拡大を防ぐ
8.iOS Safari ではダブルタップすると画面が拡大されてしまいます。例えば、ボタンなどを連打してしまったときにも画面が拡大されてしまうのは困ります。
button {
touch-action: manipulation;
}
CSS Module Scripts
9.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>
focus()
のオプション
10. preventScroll
オプションを true
にすると、フォーカスする要素が画面外にあってもスクロールしなくなります。対応していないブラウザには focus-options-polyfill を使えば対応できます。
<button>スクロールせずにフォーカスを当てる</button>
<input type="text">
document.querySelector('button').addEventListener('click', () => {
document.querySelector('input').focus({preventScroll: true})
})
Promise
エラー処理の違い
11. 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 ||= y
は x
が falsy
な値のときにのみ、x
に y
を代入します。
const user = {
id: 7,
name: '',
}
user.id ||= 1
console.log(user.id) // 7
user.name ||= 'Bob'
console.log(user.name) // Bob
x &&= y
は x
が truthy
な値のときにのみ、x
に y
を代入します。
let a = 1
let b = 0
a &&= 2
console.log(a) // 2
b &&= 2
console.log(b) // 0
x ??= y
は x
が nullish
(null
または undefined
)な値のときにのみ、x
に y
を代入します。
const user = {
id: 7,
}
user.id ??= 1
console.log(user.id) // 7
user.name ??= 'Bob'
console.log(user.name) // Bob
Promise.any()
13. 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 つでもあれば解決します。
Object.hasOwn()
14. 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))
The New CSS Reset
16.The New CSS Reset はまったく新しいリセット CSS です。
viewerjs
17.多機能なイメージビューワーライブラリです。
cropperjs
18.画像をトリミング編集できるライブラリです。
milkdown
19.プラグインで機能拡張もできる WYSIWYG マークダウンエディタのライブラリです。
slate
20.Medium や Google ドキュメントのようなリッチテキストエディタを実装できるライブラリです。
drift
21.Amazon のような商品画像にホバーすると拡大表示してくれるライブラリです。
eva.js
22.フロントエンド向けのゲームエンジンライブラリです。
svgbob
23.アスキーアートなどのダイアグラムを SVG に変換してくれるライブラリです。
wavesurfer.js
24.音声の波形を Canvas 上に描画できるライブラリです。
blurhash
25.美しいプレースホルダー画像をハッシュ値から生成・復元できるライブラリです。
spacers
26.デザインカンプのように Web ページ上の要素間の余白を調整できるライブラリです。
imaskjs
27.<input>
要素の入力値を特定の文字のみに制限できるライブラリです。
flv.js
28.Flash なしで FLV 動画を再生できるようにするライブラリです。
fzf-for-js
29.あいまい検索を実装できるライブラリです。
color
30.色形式の変換と色の変化を適用できるライブラリです。
html-to-image
31.HTML の DOM ノードを PNG や SVG などの画像として出力できるライブラリです。
filesize.js
32.ファイルサイズをわかりやすく単位つきに変換してくれるライブラリです。
zx
33.シェルスクリプトを Node.js で扱えるライブラリです。
pdfmake
34.クライアントサイドとサーバーサイド両方で PDF を生成できるライブラリです。
js-cookie
35.ブラウザの Cookie を簡単に扱えるライブラリです。
sift.js
36.MongoDB 風のクエリを扱えるライブラリです。
color-thief
37.画像からカラーパレットを生成できるライブラリです。
hyperformula
38.Excel のような表計算ができるライブラリです。
fast-deep-equal
39.高速に 2 つのオブジェクトや配列が一致しているかどうかを判定できるライブラリです。
shiki
40.美しいシンタックスコードハイライターを実装できるライブラリです。SVG 形式で書き出すこともできるようです。
pnpm
41.npm で依存モジュールのインストールを 1 箇所にまとめて、個別のプロジェクトはシンボリックリンクを用いることで軽量化と高速化を実現した Node.js ライブラリです。
AVPress
42.オンライン上で動画圧縮と書き出しができるオンラインツールです。
PhotoRoom Background Remover
43.画像の背景を自動で削除してくれるオンラインジェネレーターです。API もあり、類似サービスよりも低価格で利用できます。
Blobbb
44.SVG 形式の Blob 画像を生成できるオンラインジェネレーターです。
Unicode Arrows
45.Unicode の矢印だけを集めたサイトです。
flag-icons
46.世界の国旗の SVG 画像集です。
SVG Gobbler
47.Web サイト上の SVG 画像を編集やカスタマイズ、ダウンロードできるブラウザ拡張機能です。
No.10 ← |
Discussion