💬

No.10 2021年5,6月にツイートしたHTML/CSS/JavaScriptのTipsまとめ

2021/12/16に公開

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 で実装できるライブラリです。

https://github.com/una/CSSgram

13. egjs-flicking

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

https://github.com/naver/egjs-flicking

14. lightGallery

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

https://github.com/sachinchoolur/lightGallery

15. mojs

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

https://github.com/mojs/mojs

16. dropzone

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

https://github.com/dropzone/dropzone

17. scroll-hint

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

https://github.com/appleple/scroll-hint

18. medium-zoom

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

https://github.com/francoischalifour/medium-zoom

19. typed.js

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

https://github.com/mattboldt/typed.js

20. SimpleBar

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

https://github.com/Grsmto/simplebar

21. handsfree

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

https://github.com/midiblocks/handsfree

22. svelte-motion

Svelte 用のアニメーションライブラリです。

https://github.com/micha-lmxt/svelte-motion

23. flexsearch

JavaScript の全文検索ライブラリです。

https://github.com/nextapps-de/flexsearch

24. clipboard.js

簡単にコピー機能を実装できるライブラリです。

https://github.com/zenorocha/clipboard.js

25. jsonld.js

JSON-LD を JavaScript で扱えるプロセッサライブラリです。

https://github.com/digitalbazaar/jsonld.js

26. depcheck

npm モジュールで使われていないモジュールをチェックできるツールです。

https://github.com/depcheck/depcheck

27. css-select

CSS セレクタを右から左に解析することで高速に動作するライブラリです。

https://github.com/fb55/css-select

28. mathjs

大きな数の計算や複素数、分数や行列など JavaScript のための数値計算ライブラリです。

https://github.com/josdejong/mathjs

29. nanostores

React や Preact、Vue、Svelte で使える超軽量ストアライブラリです。

https://github.com/nanostores/nanostores

30. colorbase

コントラスト比や類似色、補色など色に関するさまざまな情報を確認できるオンラインツールです。

https://colorbase.app

31. domevents.dev

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

https://domevents.dev

32. Hero Patterns

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

https://heropatterns.com/

33. patternpad

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

https://patternpad.com/editor.html

34. Pattern Monster

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

https://pattern.monster

35. Trianglify.io

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

https://trianglify.io

36. PINTR

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

https://javier.xyz/pintr/

37. CSS Layout Generator

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

https://layout.bradwoods.io

38. Highlight Matching Tags

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

https://marketplace.visualstudio.com/items?itemName=vincaslt.highlight-matching-tag

39. Remix Icon

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

https://remixicon.com

40. Iconoir

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

https://iconoir.com

41. Akar Icons

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

https://akaricons.com


No.9 ← | → No.11


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

Discussion