Frontend Weekly 2024-08-02

Chrome 127#

2024 年 7 月 24 日に Chrome 127 がリリースされた。

https://developer.chrome.com/blog/new-in-chrome-127

CSS font-size-adjust#

CSS のfont-size-adjustプロパティがサポートされた。 これに伴い、font-size-adjustプロパティは Baseline に追加された。

フォントは、アスペクト比によって同じ font-size であっても、大きく異なる印象を与える。 ここで、アスペクト比とは、小文字の高さをフォントサイズで割った値である。

Text using 14px Verdana font appears larger than text using Times font.

Text using 14px Times font appears smaller than text using Verdana font.

font-size-adjustプロパティは、このフォントのアスペクト比を調整するために使用される。

次のように利用する。

.font-a {
font-size: 14px;
font-family: Verdana;
font-size-adjust: 0.545;
}
.font-b {
font-size: 14px;
font-family: Times;
font-size-adjust: 0.545;
}

Text using 14px Verdana font appears larger than text using Times font.

Text using 14px Times font appears smaller than text using Verdana font.

CSS content with alt text#

contentプロパティを利用して画像を表示する際に、画像の代替テキストを指定できるようになった。

<style>
.has-before-content::before {
content: url("cat.jpg") / "A cute" attr(data-animal);
}
</style>
<div class="has-before-content" data-animal="cat"></div>

Keyboard focusable scroll containers#

スクロールコンテナにキーボードでフォーカスするようになる。 以前でもtabindexを 0 以上に設定するか、スクロールコンテナ内にフォーカス可能な子要素がある場合、スクロールコンテナにフォーカスできたが、今後はどちらでもない場合でもフォーカスされる。

start content

end content

この挙動は Chrome 127 以降、徐々に展開されていく。

同意書などをスクロールコンテナ内に表示するサービスでは、開発者が十分にアクセシビリティに配慮していない場合、キーボードのみによる操作が困難であった。しかし、今後は開発者が意識しなくても、スクロールコンテナにフォーカスが当たるため、アクセシビリティが向上する。

Storybook 8.2#

Storybook 8.2 がリリースされた。テスト機能の改善や、ポータブルストーリーの正式なサポートなどが行われた。 また Storybook 8.3 では、Vitest との統合や互換性の向上が予定されている。

https://storybook.js.org/blog/storybook-8-2/

Portable stories#

ポータブルストーリーを介することで、Story をネイティブコンポーネントとして Jest や Vitest、Playwright などで再利用が出来るようになった。

Button.test.js
import { test, expect } from "vitest";
import { screen } from "@testing-library/react";
import { composeStories } from "@storybook/react";
import * as stories from "./Button.stories";
const { Primary, Secondary } = composeStories(stories);
test("renders primary button with default args", async () => {
await Primary.play();
});

Vitest や Jest でポータブルストーリーを利用する方法についてドキュメントが公開されている。

https://storybook.js.org/docs/api/portable-stories/portable-stories-jest?ref=storybookblog.ghost.io

https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest?ref=storybookblog.ghost.io

Storybook にテストの責務を持たせたくない場合や、Vitest や Jest の資産を利用したい場合など、非常に便利な機能である。

New test hooks#

Jest や Vitest、Playwright、Cypress などとより互換性のあるテストの記述が可能になった。

今まではcanvasオブジェクトを通してのみ Story のテストが可能であったが、mount メソッドが追加され他のテストフレームワークと比較的近い記述が出来るようになった。

example.stories.tsx
import { fn, expect } from "@storybook/test";
// ...
export const Disabled = {
args: { disabled: true, onSelected: fn() },
play: async ({ mount, args }) => {
// Arrange
const user = useEvent.setup();
const items = await loadItems(10);
const canvas = await mount(<ToolbarMenu items={items} />);
// Act
await user.click(canvas.getByRole("button"));
// Assert
expect(canvas.getAllByRole("button").length).toBe(items.length);
expect(args.onSelected).not.toHaveBeenCalled();
},
};

beforeEachafterEachなどは、Story ファイルの meta に記述する。

example.stories.tsx
const meta = {
// ...
async beforeEach() {
MockDate.set("2024-02-14");
// Reset the Date after each story
return () => {
MockDate.reset();
};
},
};

beforeAllafterAllは、.storybook/preview.tsに記述する。

.storybook/preview.ts
import { Preview } from "@storybook/react";
import { init } from "../project-bootstrap";
const preview: Preview = {
async beforeAll() {
await init();
},
};
export default preview;

https://storybook.js.org/docs/writing-tests/interaction-testing?ref=storybookblog.ghost.io#run-code-before-the-component-gets-rendered

個人的な感想としては、確かに名前が同じフックは生えたが、利用方法にはズレがあり、テストを CSF に変換するための学習曲線は変わらずあるように思う。

Announcing TutorialKit#

TutorialKitのアナウンスが行われた。TutorialKitは JavaScript コミュニティ向けのインタラクティブなチュートリアルを作ることが出来る Web Container ベースのツールキットである。

https://blog.stackblitz.com/posts/announcing-tutorialkit/

商用利用ではライセンスが必要だが、オープンソースでは無償で利用できる。

次のコマンドでテンプレートを作成できる。

Terminal window
npm create tutorial

How to choose the best rendering strategy for your app#

Next.js における最適なレンダリング戦略(SSG、ISR、SSR、CSR、PPR)の選び方を Vercel が解説している。

https://vercel.com/blog/how-to-choose-the-best-rendering-strategy-for-your-app

最も重要なことは、アプリケーションのユースケースに合わせて適切なレンダリング戦略を”組み合わせて”利用することである。

図や動画を交えて、それぞれのレンダリング戦略の特徴や適用例をかなり分かりやすく紹介している。

ただ長いコンテンツを読むのが面倒な場合は、現実のプロダクトでどこにどのレンダリング戦略を適用するかを書いた Real-world product rendering strategiesだけでも読んでおくと、イメージがしやすくて良いと思う。

tsconfig.json の include オプションには何を指定すべきか#

TypeScript のプロジェクトで tsconfig.json を設定する際、include オプションにはsrc/index.ts, src/**/*, **/*,srcなど、どのように指定するべきかについて解説している。

https://www.mizdra.net/entry/2024/07/27/193815

次の指定をオススメしつつ、src/index.tsのような指定はやめるように促している。

  • src/**/*またはsrcsrcディレクトリ配下をターゲットとする
  • **/*または指定なし:全てのファイルをターゲットとする

What we got wrong about HTTP imports - Deno#

Deno の開発者である Ryan Dahl が、HTTP Imports について問題を指摘した上で、それらの問題に対処するためインポートマップや JSR を導入したという話。

https://deno.com/blog/http-imports

Albert Einstein の言葉「Everything should be made as simple as possible, but not simpler.」を引用している。

Get the screen width & height without JavaScript#

CSS のみでスクリーンの幅と高さを取得する方法について解説している。

https://css-tip.com/screen-dimension/

tan(atan2(var(--_w),1px))を利用することで、vwvh単位の値をpx単位に変換している。

:root {
--w: tan(atan2(var(--_w),1px));
--h: tan(atan2(var(--_h),1px));
}

How to Get the Width/Height of Any Element in Only CSS#

CSS のみで任意の要素の幅と高さを取得する方法について解説している。

https://frontendmasters.com/blog/how-to-get-the-width-height-of-any-element-in-only-css/

Scroll-driven Animations を利用することで、要素の幅と高さを取得している。