No.10 2021年5,6月にツイートしたHTML/CSS/JavaScriptのTipsまとめ
2021 年 5, 6 月にツイートした HTML/CSS/JavaScript のツイートまとめです。見出しをクリックするとツイート元に遷移するので、気に入ったらフォロー・ファボ・リツイートお願いします。
1. gradientUnits 属性
gradientUnits 属性を使うと SVG グラデーションをアートボーと全体に対してか、図形単位に対してかを指定できます。

<svg viewBox="0 0 100 100">
<linearGradient id="gradient-1" x1="0" y1="0" x2="50%" y2="100%" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="red"/>
<stop offset="1" stop-color="blue"/>
</linearGradient>
<rect x="0" y="0" width="40%" height="100%" fill="url(#gradient-1)"/>
<rect x="60%" y="0" width="40%" height="100%" fill="url(#gradient-1)"/>
<rect x="10%" y="35%" width="80%" height="30%" fill="url(#gradient-1)"/>
</svg>
2. カーブしたリボンの形
radial-gradient() で表現しています。

<div class="shape"></div>
.shape {
width: 100px;
height: 200px;
background: radial-gradient(110% 50% at bottom, rgba(255, 255, 255, 0) 50%, #556Bda 51%);
}
3. 角丸のグラデーションボタン

<button>ボタン</button>
button {
border: 6px solid transparent;
border-radius: 12px;
background: linear-gradient(#fff, #fff) padding-box,
linear-gradient(-225deg, #473B7B 0%, #3584A7 51%, #30D2BE 100%) border-box;
}
4. 形に沿ってテキストを配置
shape-outside プロパティを float で回り込みさせることで、テキストを円形に収めることができます。

<div class="circle">
<div class="shape"></div>
そのころわたくしは...
</div>
.circle {
--size: 500px;
--padding: 20px;
width: var(--size);
height: var(--size);
color: #241d50;
border-radius: 50%;
background-color: #f5f5f5;
overflow: hidden;
}
.shape {
display: inline;
height: 100%;
}
.shape::before,
.shape::after {
width: 50%;
height: 100%;
content: '';
}
.shape::before {
float: left;
shape-outside: radial-gradient(farthest-side at right, transparent calc(100% - var(--padding)), #fff 0);
}
.shape::after {
float: right;
shape-outside: radial-gradient(farthest-side at left, transparent calc(100% - var(--padding)), #fff 0);
}
同様にして菱形も作ってみました。

<div class="rhombus">
<div class="shape"></div>
そのころわたくしは...
</div>
.rhombus {
--size: 500px;
--padding: 10px;
width: var(--size);
height: var(--size);
color: #241d50;
background-color: #f5f5f5;
clip-path: polygon(0 50%, 50% 100%, 100% 50%, 50% 0);
overflow: hidden;
}
.shape {
display: inline;
height: 100%;
}
.shape::before,
.shape::after {
width: 50%;
height: 100%;
content: '';
}
.shape::before {
float: left;
shape-outside: conic-gradient(from 45deg at var(--padding) 50%, transparent 90deg, #fff);
}
.shape::after {
float: right;
shape-outside: conic-gradient(from 225deg at calc(100% - var(--padding)) 50%, transparent 90deg, #fff);
}
5. Discord風のアイコン表示
Discord のオンライン表示のようなサムネイルの右下に切り取られた円形のあるレイアウトです。

<div class="thumb">
<img src="https://picsum.photos/id/433/500/500" alt>
</div>
.thumb {
--origin: 40px; /* 切り取る円の原点の位置 */
--mask-size: 100px; /* 切り取る円の直径 */
--circle-size: 80px; /* 内側の円(緑色)の直径 */
position: relative;
}
.thumb::after {
position: absolute;
right: calc((var(--circle-size) / 2 - var(--origin)) * -1);
bottom: calc((var(--circle-size) / 2 - var(--origin)) * -1);
width: var(--circle-size);
height: var(--circle-size);
content: '';
border-radius: 50%;
background-color: #3aa55c;
z-index: 1;
}
.thumb img {
display: block;
width: 250px;
border-radius: 50%;
-webkit-mask: radial-gradient(circle at calc(100% - var(--origin)) calc(100% - var(--origin)), transparent calc(var(--mask-size) / 2), #fff calc(var(--mask-size) / 2 + 1px));
mask: radial-gradient(circle at calc(100% - var(--origin)) calc(100% - var(--origin)), transparent calc(var(--mask-size) / 2), #fff calc(var(--mask-size) / 2 + 1px));
}
6. image-set() 関数
image-set() 関数はディスプレイ解像度に応じて背景画像を出し分けることができる機能です。Firefox もバージョン 88 から実装され、これでモダンブラウザで使えるようになりました。
.image {
width: 400px;
height: 300px;
background-image: image-set(
url(https://assets.codepen.io/221808/low-dpi-image.png) 1x,
url(https://assets.codepen.io/221808/high-dpi-image.png) 2x
);
background-size: cover;
}
古いブラウザでも使えるように Polyfill を考えてみました。
.image {
width: 400px;
height: 300px;
/* Chromium Edge, Chrome, Opera, Android */
background-image: -webkit-image-set(
url(https://assets.codepen.io/221808/low-dpi-image.png) 1x,
url(https://assets.codepen.io/221808/high-dpi-image.png) 2x
);
/* Firefox, Safari, iOS Safari */
background-image: image-set(
url(https://assets.codepen.io/221808/low-dpi-image.png) 1x,
url(https://assets.codepen.io/221808/high-dpi-image.png) 2x
);
background-size: cover;
}
/* IE, Edge */
_:-ms-lang(_), .image {
background-image: url(https://assets.codepen.io/221808/low-dpi-image.png);
}
@media (min-resolution: 192dpi) {
_:-ms-lang(_), .image {
background-image: url(https://assets.codepen.io/221808/high-dpi-image.png);
}
}
/* Firefox 88未満 */
@supports (-moz-orient: vertical) and (not selector(:user-valid)) {
.image {
background-image: url(https://assets.codepen.io/221808/low-dpi-image.png);
}
@media (min-resolution: 2dppx) {
.image {
background-image: url(https://assets.codepen.io/221808/high-dpi-image.png);
}
}
}
7. 修正されたテーブル関連の問題
Chrome 91 で修正されたテーブル関連の問題のまとめです。
サブピクセルレンダリング
Chrome 91 以前のレンダリングエンジンでは、幅 100px のテーブルがあってその中に 3 つのセルがあった場合、2 つのセルが幅 33px でもう 1 つのセルが幅 34px に丸められていました。Chrome 91 からは 3 つのセルがそれぞれ幅 33.333333px というように均等にレンダリングされます。
テーブルの列ごと非表示に
col 要素に visibility: collapse; を指定できるようになり、列ごとに非表示が可能となりました。

<table>
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead>
<tr>
<th>見出し1</th>
<th>見出し2</th>
<th>見出し3</th>
</tr>
</thead>
<tbody>
<tr>
<td>セル1</td>
<td>セル2</td>
<td>セル3</td>
</tr>
</tbody>
</table>
colgroup col:nth-child(2) {
visibility: collapse;
}
<td> 要素に writing-mode が使える

<table>
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead>
<tr>
<th>見出し1</th>
<th>少し長めの見出し2</th>
<th>見出し3</th>
</tr>
</thead>
<tbody>
<tr>
<td>セル1</td>
<td>セル2</td>
<td>セル3</td>
</tr>
</tbody>
</table>
th {
/* 縦書き */
writing-mode: vertical-rl;
/* 下揃え */
text-align: right;
}
<thead> 要素に sticky が使える
<thead> 要素に position: sticky; を指定できるようになりました。
thead {
position: sticky;
top: 0;
}
8. String#matchAll
matchAll() 関数を使うと複数のマッチのキャプチャを取得できます。
const regex = /(?<year>\d{4})\/(?<month>0?\d{1,2})\/(?<day>0?\d{1,2})/g
const text = `
2021/5/3
2021/05/03
`
console.log([...text.matchAll(regex)])
// => [
// ["2021/5/3", "2021", "5", "3"], ["2021/05/03", "2021", "05", "03"],
// ]
console.log([...text.matchAll(regex)].map(v => v.groups))
// => [
// {year: "2021", month: "5", day: "3"}, {year: "2021", month: "05", day: "03"},
// ]
9. Array#reduce とスプレッド演算子
Array.reduce() 関数で配列の数だけループされ、さらにスプレッド演算子でオブジェクトのキー分ループされるため遅くなってしまいます。
const array = [
{id: '10', name: 'HTML'},
{id: '11', name: 'CSS'},
{id: '12', name: 'JavaScript'},
]
const object = array.reduce((prev, curr) => ({
...prev,
[curr.id]: curr.name,
}), {})
console.log(object)
高速化するには、前のオブジェクトに代入するか、Map を使うとよいです。
const array = [
{id: '10', name: 'HTML'},
{id: '11', name: 'CSS'},
{id: '12', name: 'JavaScript'},
]
const object = array.reduce((prev, curr) => {
prev[curr.id] = curr.name
return prev
}, {})
console.log(object)
const array = [
{id: '10', name: 'HTML'},
{id: '11', name: 'CSS'},
{id: '12', name: 'JavaScript'},
]
const object = array.reduce((prev, curr) => {
prev.set(curr.id, curr.name)
}, new Map())
console.log(object)
10. 配列を任意の要素数で分割
const chunk = (array, size) => {
return array.reduce((prev, next, index) => {
return index % size
? prev
: [...prev, array.slice(index, index + size)]
}, [])
}
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9], 3))
// => [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9], 4))
// => [[1, 2, 3, 4], [5, 6, 7, 8], [9]]
11. ファイルの存在判定
fs.stat() 関数でファイルの存在を判定できます。
import fs from 'fs/promises`
import path from 'path'
const __dirname = path.dirname(new URL(import.meta.url).pathname)
const fileExists = async filepath => {
try {
await fs.stat(path.resolve(__dirname, filepath))
} catch {
return false
}
return true
}
12. CSSgram
Instagram のフィルターを CSS で実装できるライブラリです。

13. egjs-flicking
カスタマイズ性が高く、Angular や React、Vue でも使えるカルーセルライブラリです。

14. lightGallery
カスタマイズ性が高く、React や Vue にも対応している lightbox ライブラリです。

15. mojs
高速で Retina にも対応しているモーショングラフィックスライブラリです。

16. dropzone
ドラッグ & ドロップでファイルアップロードの UI を実装できるライブラリです。

17. scroll-hint
横スクロールテーブルなど、水平スクロールできることを示唆できるライブラリです。

18. medium-zoom
Medium 風の画像ズーム機能を実装できるライブラリです。

19. typed.js
タイピングアニメーションを実装できるライブラリです。

20. SimpleBar
カスタマイズ性が高く、パフォーマンスもよいスクロールバーライブラリです。

21. handsfree
ハンズフリーで Web ページ上のオブジェクトを操作できるようになるライブラリです。

22. svelte-motion
Svelte 用のアニメーションライブラリです。
23. flexsearch
JavaScript の全文検索ライブラリです。
24. clipboard.js
簡単にコピー機能を実装できるライブラリです。
25. jsonld.js
JSON-LD を JavaScript で扱えるプロセッサライブラリです。
26. depcheck
npm モジュールで使われていないモジュールをチェックできるツールです。
27. css-select
CSS セレクタを右から左に解析することで高速に動作するライブラリです。
28. mathjs
大きな数の計算や複素数、分数や行列など JavaScript のための数値計算ライブラリです。
29. nanostores
React や Preact、Vue、Svelte で使える超軽量ストアライブラリです。
30. colorbase
コントラスト比や類似色、補色など色に関するさまざまな情報を確認できるオンラインツールです。

31. domevents.dev
バブリングなど JavaScript の DOM イベントを視覚的に理解できるようになるオンラインツールです。

32. Hero Patterns
シームレスな SVG パターンを生成できるオンラインジェネレーターです。

33. patternpad
シームレスな SVG パターンを生成できるオンラインジェネレーターです。

34. Pattern Monster
シームレスな SVG パターンを生成できるオンラインジェネレーターです。

35. Trianglify.io
シームレスな SVG パターンを生成できるオンラインジェネレーターです。

36. PINTR
画像からシンプルな線だけの SVG 画像を生成できるオンラインジェネレーターです。

37. CSS Layout Generator
CSS Grid や Flexbox のグリッドシステムを簡単に実装できるオンラインジェネレータです。

38. Highlight Matching Tags
カーソル上の要素の開始タグと終了タグをわかりやすくハイライトしてくれる VSCode 拡張機能です。

39. Remix Icon
2000 種類以上を SVG や PNG 形式でダウンロードできるアイコン集です。

40. Iconoir
900 種類以上の SVG アイコン集です。

41. Akar Icons

300 種類以上の丸っこい SVG アイコン集です。
Discussion