Frontend Weekly 2024-08-02
Chrome 127のfont-size-adjust、Storybook 8.2のPortable stories、TutorialKitなどを紹介する。
- # Chrome 127
- # CSS font-size-adjust
- # CSS content with alt text
- # Keyboard focusable scroll containers
- # Storybook 8.2
- # Portable stories
- # New test hooks
- # Announcing TutorialKit
- # How to choose the best rendering strategy for your app
- # tsconfig.json の include オプションには何を指定すべきか
- # What we got wrong about HTTP imports - Deno
- # Get the screen width & height without JavaScript
- # How to Get the Width/Height of Any Element in Only CSS
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
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();
},
};
beforeEach
やafterEach
などは、Storyファイルのmetaに記述する。
// example.stories.tsx
const meta = {
// ...
async beforeEach() {
MockDate.set("2024-02-14");
// Reset the Date after each story
return () => {
MockDate.reset();
};
},
};
beforeAll
やafterAll
は、.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;
個人的な感想としては、確かに名前が同じフックは生えたが、利用方法にはズレがあり、テストをCSFに変換するための学習曲線は変わらずあるように思う。
Announcing TutorialKit
TutorialKit
のアナウンスが行われた。TutorialKit
はJavaScriptコミュニティ向けのインタラクティブなチュートリアルを作ることが出来るWeb Containerベースのツールキットである。
https://blog.stackblitz.com/posts/announcing-tutorialkit/
商用利用ではライセンスが必要だが、オープンソースでは無償で利用できる。
次のコマンドでテンプレートを作成できる。
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/**/*
またはsrc
:src
ディレクトリ配下をターゲットとする**/*
または指定なし:全てのファイルをターゲットとする
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))
を利用することで、vw
やvh
単位の値を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を利用することで、要素の幅と高さを取得している。