nino+ 勉強会 2024/05/09
2024/05/09
nino+ でのうちうちの勉強会のメモになります
今回はトーストの下に時間で消えるバーを作る勉強会です
(このUI天才だと思いませんか・・・?好き好き大好きすぎる)
一旦まっさらなルートディレクトリからスタート
Lorem
Loremを用いてapp/page.tsxに文言追加
(Lorem良い。ダミーのテキストを入れるのに最適。)
import Image from "next/image";
import Link from "next/link";
export default function Home() {
return (
<div>
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore modi
enim distinctio et vitae consectetur numquam, voluptates, laboriosam,
incidunt reiciendis dolorem magni? Fugit qui dolores delectus ad
inventore officiis explicabo.
</p>
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore modi
enim distinctio et vitae consectetur numquam, voluptates, laboriosam,
incidunt reiciendis dolorem magni? Fugit qui dolores delectus ad
inventore officiis explicabo.
</p>
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore modi
enim distinctio et vitae consectetur numquam, voluptates, laboriosam,
incidunt reiciendis dolorem magni? Fugit qui dolores delectus ad
inventore officiis explicabo.
</p>
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore modi
enim distinctio et vitae consectetur numquam, voluptates, laboriosam,
incidunt reiciendis dolorem magni? Fugit qui dolores delectus ad
inventore officiis explicabo.
</p>
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore modi
enim distinctio et vitae consectetur numquam, voluptates, laboriosam,
incidunt reiciendis dolorem magni? Fugit qui dolores delectus ad
inventore officiis explicabo.
</p>
</div>
);
}
```![](https://storage.googleapis.com/zenn-user-upload/5e5e86cfc21e-20240509.png)
React コンポーネントの `Props` に `React.ReactNode` を使用するメリット
React の開発において、コンポーネントのプロパティ(props)を定義する際に React.ReactNode
型を使用することには多くのメリットがあります。React.ReactNode
はReactの要素の型であり、文字列から複雑なJSX構造まで幅広い値を扱うことができるため、コンポーネントの柔軟性を大いに高めることができます。
柔軟性の拡張
React.ReactNode
を使用することで、文字列だけではなく、アイコンやその他のReact要素をタイトルとして含めることが可能になります。これにより、単なるテキスト表示よりも豊かな表現が可能となり、より複雑なユーザーインターフェースを柔軟に実装することができます。
例:
const EnhancedTitle = ({ title }: { title: React.ReactNode }) => (
<div>
<h1>{title}</h1>
</div>
);
// アイコンとテキストを含むタイトル
<EnhancedTitle title={<><img src="icon.png" alt="Icon" /> Welcome to the site!</>} />
このように React.ReactNode
を使用すると、テキストとアイコンを組み合わせたり、他のカスタムコンポーネントを埋め込んだりすることが容易になります。
string
型の使用時の厳格性
一方で、プロパティを string
型に制限することも有用です。string
型を使用する場合、プロパティに渡される値を文字列のみに限定します。これは、データの整合性を保つためや、特定のUIコンポーネントで予期しない入力を排除するために役立ちます。例えば、単にテキストデータを表示する場合や、外部からのデータ入力を文字列に限定したい場合に適しています。
const SimpleTitle = ({ title }: { title: string }) => (
<div>
<h1>{title}</h1>
</div>
);
// 文字列のみを受け付ける
<SimpleTitle title="Only text allowed" />
このProps型定義を使用すると、title
や body
プロパティに React の任意のノードを含めることができるため、より柔軟なコンポーネント設計が可能になります。たとえば、テキスト、画像、リンク、さらには他のReactコンポーネントを含めることができます。以下に、この型定義を使用したコンポーネントのコード例を示します。
コンポーネントのProps型定義と使用例
import React from 'react';
type Props = {
seconds?: number; // このプロパティはオプショナルで、数値を受け取ります。
title: React.ReactNode; // このプロパティはReactのノードを受け取ります。
body: React.ReactNode; // このプロパティもReactのノードを受け取ります。
}
const MyComponent: React.FC<Props> = ({ seconds, title, body }) => {
return (
<div>
<div>{title}</div>
<div>{body}</div>
{seconds && <span>Time: {seconds} seconds</span>}
</div>
);
};
// 使用例
export default function App() {
return (
<MyComponent
title={<h1>Welcome to My App</h1>}
body={
<div>
<p>This is an important update:</p>
<a href="https://www.example.com">Check it out here</a>
</div>
}
seconds={60}
/>
);
}
このコード例では、MyComponent
は title
, body
, および seconds
の3つのプロパティを持つコンポーネントです。title
と body
には React ノードが渡されているため、ヘッダー要素やリンクを含む複雑なHTML構造を簡単に組み込むことができます。これにより、コンポーネントの再利用性と柔軟性が大きく向上します。
まとめ
React.ReactNode
と string
のどちらを使用するかは、コンポーネントの用途と設計により異なります。より高い柔軟性と複雑なコンテンツを扱いたい場合は React.ReactNode
、厳格な文字列データを保ちたい場合は string
を選択することが推奨されます。これにより、React アプリケーションのさまざまな要求に柔軟に対応しつつ、データの整合性も保つことができます。
HTMLの仕様に沿ったコンポーネントの柔軟なコンテンツ埋め込みの実践
概要
Web開発において、コンテンツのダイナミックな埋め込みは一般的な課題です。Reactでは、コンポーネントの子要素として任意のReactノードを埋め込むことが可能ですが、その際にHTMLタグのネスティングルールを遵守する必要があります。特に、<div>
タグ内に <p>
タグを動的に挿入するケースでは注意が必要です。
問題の説明
<div>
タグの内部に <p>
タグを挿入するのは一般的ですが、その逆(<p>
タグ内に <div>
タグを挿入する)はHTMLの仕様に違反します。このため、動的コンテンツが <p>
タグである可能性がある場合、親コンテナとして <div>
を使用するのが安全です。
具体的な例
以下のReactコンポーネント例では、body
プロパティがどのような形式のコンテンツ(文字列、HTMLタグ、Reactコンポーネント)でも適切に表示されるように、<div>
タグが使用されています。
function ContentComponent({ title, body }) {
return (
<div className="border p-4 rounded-lg flex items-center">
<div>
<h2>{title}</h2>
<div>{body}</div>
</div>
</div>
);
}
詳細解説
-
HTMLのネスティングルール: HTMLでは、ブロック要素とインライン要素があり、特定のブロック要素(例えば
<p>
)の中に他のブロック要素(例えば<div>
)を配置することは禁止されています。<div>
は汎用的なコンテナとして広く用いられ、任意の形式の子要素を持つことができます。 -
React の
children
の柔軟性: React ではprops.children
を通じて、親コンポーネントが受け取る任意のReactノード(文字列、HTML、他のReactコンポーネント)を柔軟に扱うことが可能です。これにより、再利用可能で柔軟なコンポーネント設計が実現します。
まとめ
Reactで動的なコンテンツを安全に埋め込む際は、HTMLの仕様に準拠し、最も制約の少ない <div>
タグを使用することが推奨されます。これにより、コンテンツがどのような形式であっても適切に表示され、HTMLの構造上のエラーを避けることができます。このアプローチは、Webアクセシビリティとメンテナンスの容易さを保ちながら、アプリケーションのUIを柔軟に構築するための最適な方法です。
補足
<div>
タグをフラグメント化できるか?
上記コードの 紹介されている <div>
タグは、コンポーネント内に動的にコンテンツを埋め込む際に使用されています。この <div>
タグをフラグメント化することで、以下の利点と注意点が考えられます。
利点:
-
コードの簡潔化:
<div>
タグをフラグメント化することで、コードをより簡潔に記述できます。 -
再利用性の向上: フラグメント化された
<div>
タグは、他のコンポーネントでも再利用しやすくなります。 -
コンポーネントの読みやすさの向上: フラグメント化された
<div>
タグは、コンポーネントの構造をより明確に示すことができます。
注意点:
-
HTML の仕様への準拠: フラグメント化された
<div>
タグは、HTML の仕様に準拠する必要があります。特に、<p>
タグなどのブロック要素を直接子要素として含めることは避けてください。 -
アクセシビリティ: フラグメント化された
<div>
タグは、アクセシビリティに配慮する必要があります。適切なrole
属性を設定するなど、スクリーンリーダーなどの補助技術で正しく認識できるようにする必要があります。 -
メンテナンス性: フラグメント化された
<div>
タグは、メンテナンス性を考慮する必要があります。将来の変更に備え、適切な名前やコメントを記述することが重要です。
結論:
記事中の <div>
タグをフラグメント化することは、コードの簡潔化、再利用性の向上、コンポーネントの読みやすさの向上などの利点がありますが、HTML の仕様への準拠、アクセシビリティ、メンテナンス性などの注意点も考慮する必要があります。
代替案:
記事中の <div>
タグをフラグメント化せず、そのまま使用するのも有効です。この場合、コードは多少冗長になりますが、HTML の仕様への準拠やアクセシビリティに関する懸念事項を軽減できます。
最終的な判断は、プロジェクトの要件や開発者の好みによって異なります。
参考情報:
- React の Fragment ドキュメント: https://legacy.reactjs.org/docs/fragments.html
- HTML の構造に関する情報: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting/Nesting_at-rules
- Web アクセシビリティに関する情報: https://www.w3.org/TR/WCAG21/
補足:
React においてよりシンプルな構造を持ちたい場合は <>
と </>
で囲むことで、フラグメントを使うことができます。React のフラグメント (<React.Fragment>
または <>
) を使用する主な目的は、余分なDOMノードを追加せずに複数の要素をグループ化することです。
しかし、フラグメントにはクラスやその他の属性を直接適用することができません。つまり、CSSクラスを適用したい場合やその他の属性(例えば id
, style
など)が必要な場合は、フラグメントではなく div
などの具体的なHTML要素を使用する必要があります。
以下にコンポーネントの構造の例を示します:
export default function TimerAlert({ seconds = 5, title, body }: Props) {
useEffect(() => {
setTimeout(() => {
console.log("Time's up!");
}, seconds * 1000);
}, []); // 依存配列が空なので、コンポーネントのマウント時に一度だけ実行されます。
return (
<div className="border p-4 rounded-lg">
<h2>{title}</h2>
<div>{body}</div> //Body内には<p>タグが入ってくる可能性もある。<P>タグin<pタグ>にすることができないのでここでは<div>要素を当てている
</div>
);
}
この例では、フラグメント <></>
ではなく div
を使用しています。これは、className
などの属性を div
に適用することができるためです。もし div
が不要で、クラスなどの属性の適用が必要なければ、フラグメントを使用しても問題ありませんが、上述のように属性を適用することはできません。
記事中の <div>
タグは、単なるコンテナとして使用されています。そのため、特別な意味を持つものではありません。フラグメント化することで、コードをより簡潔に記述できますが、必須ではありません。
JavaScript における `setTimeout` 関数の概要と使用方法
JavaScript で時間遅延や非同期処理を管理する際に非常に便利なのが setTimeout
関数です。この関数は指定された時間が経過した後に、一度だけ関数を実行します。ウェブ開発においては、様々なシナリオでこの関数が使われます。
setTimeout
関数の基本的な構文:
setTimeout(function, delay, ...args);
- function: 実行される関数。
- delay: 遅延時間(ミリ秒単位)。
- ...args: 関数に渡される追加の引数(オプション)。
使用例
setTimeout(() => {
console.log("Hello after 3 seconds");
}, 3000);
このコードは、3秒後にコンソールに "Hello after 3 seconds" と表示します。
setTimeout
の利用シナリオ
-
ユーザーへのフィードバックの遅延表示:
ユーザーがフォームを送信した後、"送信完了" のメッセージを数秒間表示してから消すなど、ユーザーに時間をかけて情報を伝える場合に使います。 -
アニメーションのタイミング制御:
複数のアニメーションを順番に実行するために、setTimeout
を使って次のアニメーションが開始するまでの遅延を設定します。 -
データの非同期処理:
例えば、ユーザーの操作後にデータのロードを少し遅らせて、ローディングアイコンを表示するなどの処理に利用されます。
注意点
-
非同期実行:
setTimeout
は非同期で実行されるため、setTimeout
のコールが終了する前にプログラムの次の行が実行されることがあります。これにより、意図しないタイミングの問題が発生することがあります。 -
最小遅延時間:
実際の遅延時間はブラウザや環境によって最小値が設定されていることがあるため、非常に短い遅延時間を設定しても、その時間よりも長くなることがあります。
setTimeout
は、プログラムに一定の遅延を加える簡単で強力な方法ですが、その非同期性を理解し、適切に管理することが重要です。これにより、ウェブアプリケーションのユーザーエクスペリエンスを向上させることができます。
小技集
VSCodeにこの拡張を追加
rfc(react function component)と打つと最小のコンポーネント構成が表示される
好きなところ
arert-timer.tsx というファイル名にしている場合、rfcで自動的に作成される関数名がArertTimer()
になるところ
(他の拡張機能だとArert-Timer()
のように訳わからないことになってエラーが発生していた)
ファイルを追加していく
command + shift + p
でコマンドパレットを展開
>nefi
で新規ドキュメント作成
components ディレクトリ配下に今回作りたいコンポーネント(timer-alert.tsx)を作成
実装で用いたCSSまとめ
border
クラスとその類似機能を持つCSSクラス
CSSクラス名 | 機能説明 | 使用例 |
---|---|---|
border |
標準的な1pxの境界線を追加します。 | <div class="border">Content</div> |
border-2 |
2pxの境界線を追加します。 | <div class="border-2">Content</div> |
border-t |
上辺にのみ境界線を追加します。 | <div class="border-t">Content</div> |
border-none |
境界線を削除します(既存の境界線を無効化)。 | <div class="border-none">No Border</div> |
border-dashed |
点線の境界線を追加します。 | <div class="border-dashed">Dashed Border</div> |
border-solid |
実線の境界線を追加します(多くの場合、デフォルトのスタイル)。 | <div class="border-solid">Solid Border</div> |
border-color |
境界線の色を指定します(例: border-red-500 )。 |
<div class="border border-red-500">Colored Border</div> |
機能の説明
-
基本的な境界線 (
border
): 最も一般的に使用されるクラスで、要素全体に薄い枠線を追加します。デフォルトは通常solid
スタイルの黒またはグレーです。 -
太い境界線 (
border-2
): 通常のborder
よりも太い境界線を設定します。これは視覚的な強調や重要なセクションを区切る際に有用です。 -
部分的な境界線 (
border-t
): 特定の辺にのみ境界線を設定します。例えばborder-t
は上辺にのみ境界線を追加します。これはグループ化された項目間の区切りとしてよく用いられます。 -
境界線の削除 (
border-none
): 要素から全ての境界線を削除します。これはデザイン上の選択肢として、他のデザイン要素との組み合わせにより使われます。 -
点線境界線 (
border-dashed
): 境界線を点線スタイルで設定します。警告や注意を引くためのセクションに用いることが多いです。
CSSクラスp-4
とその類似のパディングクラスに関する詳細と比較を以下の表にまとめました。p-4
は特定のパディング量を設定するために使用され、これに類似する他のクラスも様々なパディングオプションを提供します。
p-4
クラスと類似機能を持つCSSクラス
CSSクラス名 | 機能説明 | 使用例 |
---|---|---|
p-4 |
要素の全方向にパディングを1.5rem(約24px)追加します。 | <div class="p-4">Content</div> |
p-2 |
要素の全方向にパディングを0.5rem(約8px)追加します。 | <div class="p-2">Content</div> |
p-8 |
要素の全方向にパディングを2rem(約32px)追加します。 | <div class="p-8">Content</div> |
px-4 |
要素の左右にのみパディングを1.5rem(約24px)追加します。 | <div class="px-4">Content</div> |
py-4 |
要素の上下にのみパディングを1.5rem(約24px)追加します。 | <div class="py-4">Content</div> |
pt-4 |
要素の上にのみパディングを1.5rem(約24px)追加します。 | <div class="pt-4">Content</div> |
pb-4 |
要素の下にのみパディングを1.5rem(約24px)追加します。 | <div class="pb-4">Content</div> |
機能の説明
-
p-4
: これは最も汎用的なパディングクラスで、要素の全方向に一定のパディングを追加します。主に要素に均一の空間を提供し、コンテンツが端に詰まるのを防ぐために使用されます。 -
p-2
,p-8
: これらはp-4
と同様に全方向にパディングを追加しますが、その量が異なります。小さなパディングが必要な場合や、より多くの空間が必要な場合に適しています。 -
px-4
,py-4
: これらのクラスは特定の方向(水平または垂直)にのみパディングを適用します。特定のレイアウトニーズに応じて、水平方向または垂直方向にのみ空間を追加することができます。 -
pt-4
,pb-4
: これらは特定の側(上または下)にのみパディングを追加します。例えば、リストのアイテム間に空間を追加したい場合などに使用します。
これらのクラスを適切に組み合わせることで、Webページ上での要素の配置と視覚的快適さを効果的に制御できます。
rounded-lg
と類似のCSSクラス
CSSクラス名 | 機能説明 | 使用例 |
---|---|---|
rounded-lg |
要素の角を大きく丸くします。 | <div class="rounded-lg">Content</div> |
rounded-sm |
要素の角をわずかに丸くします。 | <div class="rounded-sm">Content</div> |
rounded-md |
要素の角を中程度に丸くします。 | <div class="rounded-md">Content</div> |
rounded-full |
要素の角を完全に円形にします。 | <div class="rounded-full">Content</div> |
rounded-none |
要素の角の丸みを取り除きます。 | <div class="rounded-none">Content</div> |
rounded-t-lg |
要素の上側の角だけを大きく丸くします。 | <div class="rounded-t-lg">Content</div> |
rounded-b-lg |
要素の下側の角だけを大きく丸くします。 | <div class="rounded-b-lg">Content</div> |
機能の説明と使用例
-
rounded-lg
:- 機能: 要素の全角を一定の大きさで丸くする。適度に強調された丸みが特徴。
- 使用例: ボタンや入力フィールドなどのUIコンポーネントで使うと良い視覚的な調和が得られます。
-
rounded-sm
,rounded-md
,rounded-full
,rounded-none
:-
機能: それぞれのクラスは丸みの度合いを調整します。
rounded-sm
は軽い丸みを、rounded-md
は中程度の丸みを提供します。rounded-full
は完全な円を形成し、rounded-none
は丸みを解除します。 -
使用例: 小さな要素や装飾的な要素には
rounded-sm
やrounded-md
、アバターやアイコンにはrounded-full
が適しています。
-
機能: それぞれのクラスは丸みの度合いを調整します。
-
rounded-t-lg
,rounded-b-lg
:-
機能: 特定の側面のみを丸くすることができます。
rounded-t-lg
は上辺、rounded-b-lg
は下辺の角のみを丸くします。 - 使用例: カードのヘッダーやフッターに特有のスタイルを適用する場合に便利です。
-
機能: 特定の側面のみを丸くすることができます。
これらのクラスを使うことで、Webページのデザインにおける柔らかさや親しみやすさを効果的に調節することができます。適切なクラスの選択は、コンテンツの視覚的な魅力を高め、ユーザーの体験を向上させます。
flex
クラスと類似機能を持つCSSクラスの比較
CSSクラス名 | 機能説明 | 使用例 |
---|---|---|
flex |
Flexbox レイアウトを有効にします。 | <div class="flex">...</div> |
inline-flex |
インライン要素としてのFlexbox レイアウトを有効にします。 | <div class="inline-flex">...</div> |
grid |
CSS Grid レイアウトを有効にします。 | <div class="grid">...</div> |
flex-row |
Flexbox アイテムを水平方向に配置します。 | <div class="flex flex-row">...</div> |
flex-col |
Flexbox アイテムを垂直方向に配置します。 | <div class="flex flex-col">...</div> |
機能の説明と使用例
flex
- 機能: コンテナ内のアイテムを柔軟に配置し、応答性の高いレイアウトを実現します。
-
使用例:
<div class="flex"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> </div>
inline-flex
- 機能: Flexboxの特性を保ちつつ、要素をインラインで配置します。これにより、テキストと同じ行上にFlexboxアイテムを並べることができます。
-
使用例:
<div class="inline-flex"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> </div>
grid
- 機能: より複雑なレイアウトを可能にするCSS Grid レイアウトを有効にします。この方法は、行と列の両方で要素を配置するのに適しています。
-
使用例:
<div class="grid grid-cols-3 grid-rows-2"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> <div>Item 4</div> <div>Item 5</div> <div>Item 6</div> </div>
flex-row
と flex-col
-
機能 (
flex-row
): Flexbox アイテムを行方向に配置します。 -
機能 (
flex-col
): Flexbox アイテムを列方向に配置します。 -
使用例:
<!-- Row 方向 --> <div class="flex flex-row"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> </div> <!-- Column 方向 --> <div class="flex flex-col"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> </div>
これらのクラスを適切に使用することで、Webページのレイアウトを柔軟に、そして効率的に設計することができます。それぞれのクラスは特定のレイアウトニーズに応じて選択し、適用することが重要です。
CSSアニメーションに関して
この記事では、CSS アニメーションの動きを理解するために必要な用語と概念を説明します。
用語
- イージング: アニメーションの動きを制御するものです。アニメーションの開始と終了の速度、または速度の変化を指定できます。
- トランジション: アニメーションの開始と終了を制御するものです。アニメーションの開始と終了のタイミング、またはアニメーションの動きを制御できます。
- イーズイン: アニメーションの開始時に速度が徐々に速くなります。
- イーズアウト: アニメーションの終了時に速度が徐々に遅くなります。
- イーズインアウト: アニメーションの開始時に速度が徐々に速くなり、終了時に速度が徐々に遅くなります。
- リニア: アニメーションの速度が一定です。
概念
- アニメーションの動き: アニメーションのオブジェクトがどのように動くかです。オブジェクトは、移動、回転、拡大、縮小などできます。
- アニメーションの開始: アニメーションが開始されるタイミングです。
- アニメーションの終了: アニメーションが終了するタイミングです。
- アニメーションの速度: アニメーションのオブジェクトが動く速さです。
-
transform:
scaleX(1)
- 要素のX軸方向の拡大縮小を指定します。ここでは
1
を指定しているので、元のサイズのままです。
- 要素のX軸方向の拡大縮小を指定します。ここでは
-
transitionDuration:
${seconds}s
- トランジションにかける時間を秒単位で指定します。ここでは、
seconds
という変数を使用しており、JavaScriptなどで動的に値を設定できるようになっています。
- トランジションにかける時間を秒単位で指定します。ここでは、
-
className="absolute ease-linear bottom-0 origin-left inset-x-0"
-
absolute
: 要素を絶対位置指定します。 -
ease-linear
: トランジションのタイミング関数を指定します。linear
は一定の速度で変化します。 -
bottom-0
: 要素の下側の位置を0に設定します。 -
origin-left
: トランジションの変化の基点を左側に設定します。 -
inset-x-0
: 要素の左右の位置を0に設定します。
-
ease
とease-linear
の違いは、トランジションの変化の仕方が異なります。ease
はゆっくり始まり、中間で速くなり、最後にまたゆっくりになります。一方、ease-linear
は一定の速度で変化します。
このコードを使用することで、要素が左側から現れ、一定の速度で右側へ移動し、最後に消えるようなアニメーションを実現できます。トランジションを使用することで、要素の状態変化を滑らかに表現でき、ユーザーにとって見やすく自然なアニメーションを作成できます。
補足
以下は、CSSにおける transition
と ease
を用いた基本的なコード例です。
/* 要素のサイズ変更にトランジションを適用する */
.size-transition {
width: 100px;
height: 100px;
background-color: lightblue;
transition: width 2s ease-in-out;
}
.size-transition:hover {
width: 200px;
}
/* カラーの変更にトランジションを適用する */
.color-transition {
color: black;
transition: color 1s ease;
}
.color-transition:hover {
color: red;
}
用途比較表
プロパティ | 説明 | 用途例 |
---|---|---|
transition |
指定した時間をかけてCSSプロパティの変更を適用します。 | 要素のサイズ、色、位置などの変更に使用し、変更が急ではなく滑らかに感じられるようにします。 |
ease |
アニメーションの速度が徐々に変化し、自然な動きを作り出します。開始と終了はゆっくりで、中間は速いです。 | ボタンのホバーエフェクト、画面遷移などの視覚的なフィードバックに適しています。 |
ease-in |
アニメーションがゆっくり始まり、次第に速くなります。 | 要素が画面に入る際のアニメーションなど、開始を強調したい場合に使用します。 |
ease-out |
アニメーションが速く始まり、ゆっくりと終わります。 | 要素が画面から出る際のアニメーションなど、終了をなめらかにしたい場合に使用します。 |
ease-in-out |
アニメーションがゆっくり始まり、中間で速く、またゆっくり終わります。 | 開始と終了の両方を滑らかにしたいとき、または状態の変化が頻繁に起こる要素に適しています。 |
この表に基づいて、それぞれのプロパティの適切な使用例を選ぶことができます。例えば、要素が画面に現れるときには ease-in
を、消えるときには ease-out
を使うことで、より自然な動きが実現できます。
動くようになりました
この箇所でTailwind CSSとCSSを併用する理由
Tailwind CSSは、ユーティリティファーストのCSSフレームワークとして、開発者の生産性を高め、統一されたスタイルを実現する強力なツールです。しかし、すべてのケースにおいてTailwind CSSだけで完結できるわけではありません。親コンポーネントから渡された値に基づいて動的にスタイルを変更したい場合などは、Tailwind CSSとCSSを併用することで、より柔軟な開発を実現できます。
1. 動的なスタイル制御の必要性
Tailwind CSSは、様々なユーティリティクラスを提供することで、豊富なスタイルを簡単に適用できます。しかし、コンポーネントのスタイルを親コンポーネントから渡された値に基づいて動的に変更したい場合、Tailwind CSSだけでは十分ではありません。
例えば、以下のコンポーネントを想像してみてください。
const Button = ({ color, size }) => {
return (
<button className={`bg-${color} text-white px-4 py-2 rounded-md ${size === 'large' ? 'text-xl' : 'text-base'}`}>
ボタン
</button>
);
};
このコンポーネントは、color
とsize
というプロップを受け取り、ボタンの背景色、文字色、サイズを変更することができます。しかし、特定の条件に基づいてスタイルをさらに変化させたい場合、Tailwind CSSだけでは難しい場合があります。
2. ReactでCSSを併用する方法
このような場合、Reactのstyle
プロパティを用いて、CSSを直接記述することで、動的なスタイル制御を実現できます。
const Button = ({ color, size, disabled }) => {
const styles = {
backgroundColor: color,
color: 'white',
padding: '4px 12px',
borderRadius: '4px',
fontSize: size === 'large' ? '18px' : '16px',
cursor: disabled ? 'not-allowed' : 'pointer',
};
if (disabled) {
styles.opacity = 0.5;
}
return (
<button className="rounded-md" style={styles}>
ボタン
</button>
);
};
上記のように、style
プロパティにオブジェクトを定義することで、コンポーネントのスタイルを動的に設定できます。このオブジェクトには、CSSプロパティ名と値をキー・バリュー形式で記述します。
style
プロパティを用いるメリット
- 親コンポーネントから渡された値に基づいて、スタイルを柔軟に制御できます。
- 特定の条件に基づいて、スタイルを変化させることができます。
- Tailwind CSSと組み合わせることで、より複雑なスタイルを実現できます。
style
プロパティを用いるデメリット
- Tailwind CSSのユーティリティクラスを直接使用できないため、コード量が増える可能性があります。
- スタイルの命名規則や管理が煩雑になる可能性があります。
3. 使い分けのポイント
Tailwind CSSとCSSを併用する際には、以下の点を意識すると良いでしょう。
- Tailwind CSSで実現できるスタイルは、Tailwind CSSで記述する
- 動的なスタイル制御や、複雑なスタイルは、CSSで記述する
- スタイルの命名規則や管理を統一する
- 必要に応じて、CSS in JSライブラリなどを活用する
4. まとめ
ReactでTailwind CSSとCSSを併用することで、より柔軟な開発を実現できます。それぞれのメリットとデメリットを理解し、状況に応じて使い分けることが重要です。
参考情報
- React で CSS を使う [無効な URL を削除しました]
- Tailwind CSS ドキュメント
- CSS in JS ライブラリ [無効な URL を削除しました]
React.ReactNodeでタイトルを受け取れるから<strong>{title}</strong>のような書き方もできる。素晴らしい。
Lucidaアイコンについて
使用例
import { Info, TriangleAlert, Ban } from 'lucide-react';
const icon = {
info: <Info />,
warning: <TriangleAlert />,
error: <Ban />
};
// 使用する例
function displayNotification(type) {
return <div>{icon[type]}</div>;
}
Lucide.dev: 高品質で無料の SVG アイコンセット
Lucide.dev は、オープンソースの SVG アイコンセットを提供する Web サイトです。1,000 以上の高品質なアイコンが用意されており、商用利用も可能です。
主な機能:
- 豊富なアイコン: ウェブ開発、デザイン、ソフトウェア開発など、さまざまな分野に使える幅広いアイコンが揃っています。
- 高品質: すべてのアイコンは SVG 形式で提供され、拡大縮小しても鮮明なままです。
- カスタマイズ可能: 色、サイズ、ストローク幅などを自由にカスタマイズできます。
- オープンソース: MIT ライセンスで配布されているため、商用利用も可能です。
- 使いやすい: Web サイトから簡単にアイコンを検索してダウンロードできます。
プロジェクトで Lucide.dev アイコンを使用する方法:
1. アイコンを選択する:
- Lucide.dev Web サイトにアクセスし、目的のアイコンを検索します。
- カテゴリ、キーワード、タグを使って絞り込み検索できます。
- 気に入ったアイコンを見つけたら、詳細ページを開きます。
2. アイコンをダウンロードする:
- 詳細ページで、必要な形式 (SVG、PNG、ICO など) とサイズを選択します。
- "Download" ボタンをクリックして、アイコンをダウンロードします。
3. プロジェクトにアイコンを追加する:
- ダウンロードしたアイコンファイルをプロジェクトにコピーします。
- HTML コードで
<img>
タグを使用してアイコンを表示します。
例:
<img src="path/to/icon.svg" alt="Lucide icon">
4. アイコンをカスタマイズする (オプション):
- SVG ファイルをテキストエディタで編集して、色、サイズ、ストローク幅などをカスタマイズできます。
- コードエディタでアイコンの CSS スタイルを編集することもできます。
Lucide.dev へのコントリビュート:
Lucide.dev はオープンソースプロジェクトなので、誰でも貢献できます。アイコンの作成、バグ修正、ドキュメントの改善など、さまざまな方法で貢献できます。
参考情報:
- Lucide.dev Web サイト: https://lucide.dev/
- Lucide.dev GitHub リポジトリ: https://github.com/lucide-icons/lucide
- Lucide.dev ドキュメント: https://lucide.dev/icons/
まとめ:
Lucide.dev は、高品質で無料の SVG アイコンセットを探している開発者やデザイナーにとって貴重なリソースです。豊富なアイコン、カスタマイズ性、使いやすさ、オープンソース性など、多くのメリットがあります。ぜひ Lucide.dev を利用して、プロジェクトに魅力的なアイコンを追加してみてください。
:::
実装で用いたTailWind CSSまとめ
container
クラスと類似機能
Tailwind CSS の Tailwindクラス名 | 機能説明 | 使用例 |
---|---|---|
container |
コンテンツを中央に配置し、デフォルトの最大幅を設定します。デザインのブレークポイントに応じて調整されます。 | <div class="container">...</div> |
w-full |
要素の幅をビューポートの100%に設定します。 | <div class="w-full">...</div> |
mx-auto |
要素の左右のマージンを自動に設定し、中央寄せを実現します。 | <div class="mx-auto">...</div> |
max-w-screen-sm , max-w-screen-md , max-w-screen-lg , max-w-screen-xl
|
特定のブレークポイントに応じた最大幅を設定します。 | <div class="max-w-screen-md">...</div> |
機能の説明と使用例
container
- 機能: コンテナは自動的に最大幅をブレークポイントに応じて調整し、中央寄せします。これにより、内容が読みやすく、デザインが整った形で表示されます。
-
使用例:
<div class="container"> <p>This is a centered paragraph within a Tailwind container.</p> </div>
w-full
と mx-auto
-
機能 (
w-full
): 要素をビューポートの全幅に広げます。 -
機能 (
mx-auto
): 要素を水平方向に中央に配置します。 -
使用例:
<div class="w-full mx-auto"> <p>This paragraph will use the full width of the viewport and be centered.</p> </div>
max-w-screen-*
)
ブレークポイント固有の最大幅クラス (- 機能: 特定のデバイスサイズ(スモール、ミディアム、ラージ、エクストララージ)に適した最大幅を設定します。
-
使用例:
<div class="max-w-screen-md"> <p>This content will have a maximum width suitable for medium devices.</p> </div>
Tailwind CSSの flex
クラスとその類似機能を持つクラスについて説明します。flex
はCSS Flexboxを使って要素を柔軟に配置するためのユーティリティクラスです。以下に、flex
と関連する他のクラスを比較し、その使用方法を示します。
flex
クラスと類似機能を持つクラスの比較
Tailwind CSS の Tailwindクラス名 | 機能説明 | 使用例 |
---|---|---|
flex |
Flexbox コンテナを作成し、子要素をフレックスアイテムとして扱います。 | <div class="flex">...</div> |
inline-flex |
Flexbox コンテナをインライン要素として扱います。 | <div class="inline-flex">...</div> |
flex-row |
子要素を水平方向に並べます(標準設定)。 | <div class="flex flex-row">...</div> |
flex-col |
子要素を垂直方向に並べます。 | <div class="flex flex-col">...</div> |
grid |
CSS Grid レイアウトを有効にします。 | <div class="grid">...</div> |
inline-grid |
CSS Grid レイアウトをインライン要素として扱います。 | <div class="inline-grid">...</div> |
機能の説明と使用例
flex
- 機能: Flexbox を使って子要素を柔軟に配置します。デフォルトでは、子要素は行方向に並びます。
-
使用例:
<div class="flex"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> </div>
inline-flex
-
機能:
flex
と同じ振る舞いをしますが、コンテナはインライン要素として扱われます。 -
使用例:
<div class="inline-flex"> <div>Item 1</div> <div>Item 2</div> </div>
flex-row
と flex-col
-
機能 (
flex-row
): 子要素を水平方向に配置します。 -
機能 (
flex-col
): 子要素を垂直方向に配置します。 -
使用例:
<!-- Row 方向 --> <div class="flex flex-row"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> </div> <!-- Column 方向 --> <div class="flex flex-col"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> </div>
grid
と inline-grid
-
機能 (
grid
): CSS Grid を使ってより複雑なレイアウトを実現します。列と行を使って要素を配置できます。 -
機能 (
inline-grid
):grid
の機能を持ちつつ、コンテナがインライン要素として扱われます。 -
使用例:
<div class="grid grid-cols-3"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> </div>
このスクリーンショットに示されているコードは、Tailwind CSSを使用したHTML要素のスタイリングの例です。クラス名からその機能を詳しく解析し、類似機能を持つクラスとともに比較表を作成します。
コードの解析
<div className="absolute bottom-0 inset-x-0 h-2 bg-red-500"></div>
この要素は以下のスタイルが適用されています:
-
absolute
: 要素を絶対位置で配置します。 -
bottom-0
: 要素の下端を親要素の下端に揃えます。 -
inset-x-0
: 要素の左右の位置を親要素の左右端に揃えます。 -
h-2
: 要素の高さを0.5remに設定します。 -
bg-red-500
: 要素の背景色を赤色のトーン500に設定します。
類似機能を持つTailwind CSSクラスとの比較
Tailwindクラス名 | 機能説明 | 使用例 |
---|---|---|
absolute |
要素を絶対位置で配置します。 | <div class="absolute">...</div> |
fixed |
要素を画面に対して固定位置で配置します。 | <div class="fixed">...</div> |
relative |
要素を相対位置で配置し、子要素の位置基準点とします。 | <div class="relative">...</div> |
bottom-0 |
要素の下端を親または最近の位置指定要素の下端に合わせます。 | <div class="bottom-0">...</div> |
inset-x-0 |
要素の左右の位置を親の左右端に揃えます。 | <div class="inset-x-0">...</div> |
inset-y-0 |
要素の上下の位置を親の上下端に揃えます。 | <div class="inset-y-0">...</div> |
h-2 |
要素の高さを0.5remに設定します。 | <div class="h-2">...</div> |
h-4 |
要素の高さを1remに設定します。 | <div class="h-4">...</div> |
bg-red-500 |
要素の背景色を赤色のトーン500に設定します。 | <div class="bg-red-500">...</div> |
bg-blue-500 |
要素の背景色を青色のトーン500に設定します。 | <div class="bg-blue-500">...</div> |
使用例
以下は、このクラス組み合わせを使用して、画面の下部に赤いバーを作成する例です:
<div class="relative w-full h-screen">
<div class="absolute bottom-0 inset-x-0 h-2 bg-red-500"></div>
</div>
この例では、relative
で指定された親要素に対して、子要素が絶対位置で底辺に赤いバーとして配置されています。このようにTailwind CSSを使用することで、HTML要素に対して直感的かつ迅速にスタイルを適用することが可能です。
Tailwind CSS でバーを狭める: with vs transform
Tailwind CSS でバーを狭めるには、width
プロパティや flex
ユーティリティを使うのが一般的です。しかし、with
プロパティを使う方法も存在します。
従来、with
プロパティはバーを狭めるために広く使われていました。しかし、近年では transform
プロパティが推奨されています。
with
プロパティの使用:
.bar {
width: 100px; /* 元の幅 */
with: 50px; /* 幅を50pxに狭める */
}
width アニメーションの問題点
width プロパティをアニメーションすると、ブラウザは多くの再計算を行う必要があります。具体的には、要素の幅が変わるたびに、ページのレイアウトを更新する必要が出てきます。これは「リフロー」と呼ばれ、ページの他の要素にも影響を及ぼす可能性があります。特に、DOM要素が多い大規模なアプリケーションでは、このリフローがパフォーマンスのボトルネックになることがあります。
transform
プロパティの使用:
.bar {
width: 100px; /* 元の幅 */
transform: scaleX(0.5); /* 横方向に50%縮小 */
}
transform アニメーションの利点
一方で、transform: scaleX() を使うアプローチは、要素の形状を変形させることで幅を調整します。transform はコンポジットレイヤー内で処理されるため、レイアウト計算の影響を受けず、GPUによるハードウェアアクセラレーションの恩恵を受けることが多いです。結果として、transform を用いたアニメーションは滑らかで、パフォーマンス効率が良好です。
with
プロパティと transform
プロパティの比較:
項目 |
with プロパティ |
transform プロパティ |
---|---|---|
アニメーション | ぎこちない | 滑らか |
ブラウザ負荷 | 大きい | 小さい |
レイアウトへの影響 | レイアウトを崩す可能性がある | レイアウトを崩さない |
対応ブラウザ | 古いブラウザでは動作しない可能性がある | ほとんどのブラウザに対応している |
結論:
一般的には、transform
プロパティの方が with
プロパティよりもアニメーションが滑らかで、ブラウザへの負荷も小さいため、バーを狭めるために推奨されています。
ただし、with
プロパティは古いブラウザでの対応が必要な場合や、レイアウトへの影響を最小限に抑えたい場合などに役立つ可能性があります。
補足:
-
transform
プロパティは、要素を回転、移動、縮小、拡大などの変換を行うために使用できます。 -
scaleX
プロパティは、要素の横方向のスケールを変更します。 -
scaleY
プロパティは、要素の縦方向のスケールを変更します。 -
scale
プロパティは、要素の横方向と縦方向のスケールを同時に変更します。
これらのプロパティを組み合わせて、バーを様々な方法で狭めることができます。
参考情報:
- Tailwind CSS ドキュメント: https://v2.tailwindcss.com/docs/transform
- CSS Transform Module Level 3: https://www.w3schools.com/cssref/css3_pr_transform.php
Tailwind CSS v3.0 で導入された「arbitrary values(任意の値)」に関して(便利)
Tailwind CSS v3.0 で導入された「arbitrary values(任意の値)」機能により、従来の duration-75
、duration-100
といった固定値の持続時間クラスに加えて、duration-[value]
構文を使って任意の持続時間値を手動で設定できるようになりました。
従来の固定値の持続時間クラスは、あらかじめ用意された限られた選択肢から選択する必要がありましたが、duration-[value]
構文を使用すれば、これらの選択肢にとらわれずに、ミリ秒単位で任意の値を設定できます。
例:
<div class="animate-pulse duration-500">
</div>
<div class="animate-pulse duration-[1234ms]">
</div>
duration-[value]
構文を使用する際の注意点:
- 値を角括弧
[]
で囲む必要があります。 - 単位を含む値を指定する必要があります (例:
px
、ms
、%
など)。 - この機能は、Tailwind CSS のデフォルト設定から外れるため、必要な場合にのみ使用する必要があります。
duration-[value]
構文の利点:
- 従来の Tailwind CSS の持続時間クラスでは利用できなかった任意の持続時間値を設定できます。
- より詳細なアニメーション制御が可能になります。
- コードの可読性を向上させることができます。
duration-[value]
構文の注意点:
- 全てのブラウザで完全にサポートされているわけではありません。
- Tailwind CSS のデフォルト設定から外れるため、一貫性を保つために注意が必要です。
代替方法:
- Tailwind CSS のデフォルトの持続時間クラスを使用する。
-
transition-duration
プロパティを使って、インライン CSS でアニメーションの持続時間を設定する。 - JavaScript を使用して、アニメーションの持続時間を動的に設定する。
まとめ:
duration-[value]
構文は、Tailwind CSS でアニメーションの持続時間をより柔軟に制御するための強力なツールですが、注意点も存在します。
cn ( className ) について
ありがとうございます。画像を見ると、cn
は className
の値として使われている関数のようです。これはおそらく classnames
または類似のユーティリティ関数で、複数のクラス名を条件付きで組み合わせるために使用されます。classnames
ライブラリは JavaScript または TypeScript プロジェクトでよく使用され、React などのコンポーネントベースのフレームワークで特に便利です。
classnames
ライブラリの基本
classnames
は、複数のクラス名を動的に組み合わせるためのライブラリです。これにより、コンポーネントの状態やプロップに基づいてクラス名を切り替えることが容易になります。
インストール方法
npm install classnames
基本的な使用法
import classNames from 'classnames';
function Button({ primary, children }) {
const btnClass = classNames({
'btn': true,
'btn-primary': primary,
'btn-secondary': !primary
});
return <button className={btnClass}>{children}</button>;
}
classnames
を使用した Tailwind CSS との組み合わせ
Tailwind CSS と classnames
を組み合わせることで、さまざまなスタイルの条件付き適用が非常にシンプルになります。例えば、特定の条件下で異なるテーマのボタンを表示する場合などに便利です。
例:条件付きスタイリング
function ThemedButton({ theme }) {
const buttonClass = classNames(
'px-4 py-2 rounded-md text-white font-bold',
{
'bg-blue-500 hover:bg-blue-700': theme === 'blue',
'bg-red-500 hover:bg-red-700': theme === 'red',
}
);
return <button className={buttonClass}>Press me</button>;
}
このコードでは、theme
プロップに応じてボタンの背景色とホバー時の色が変わります。このように classnames
を使用することで、React コンポーネントの動的なスタイリングが直感的かつ効率的に行えます。
TailwindCSSで要素の透明度を制御する
TailwindCSSとは
TailwindCSSは、HTMLのclassを使ってスタイリングを行うユーティリティファーストのCSSフレームワークです。
opacityユーティリティクラス
TailwindCSSのopacityユーティリティクラスは、要素の透明度を制御するために使用されます。値が小さいほど透明になり、100で完全に不透明になります。
opacityユーティリティクラスの使い方
基本的な使い方
<div class="opacity-0">完全に透明な要素</div>
<div class="opacity-25">25%の不透明度の要素</div>
<div class="opacity-50">50%の不透明度の要素</div>
<div class="opacity-75">75%の不透明度の要素</div>
<div class="opacity-100">完全に不透明な要素</div>
レスポンシブデザインへの応用
<div class="opacity-0 lg:opacity-100">
大きな画面サイズでは不透明、小さな画面サイズでは透明な要素
</div>
透明度の活用シーン
オーバーレイ
<div class="relative">
<img src="image.jpg" alt="背景画像">
<div class="absolute inset-0 bg-black opacity-50"></div>
<div class="absolute inset-0 flex items-center justify-center text-white">
<h2>オーバーレイテキスト</h2>
</div>
</div>
ホバーエフェクト
<button class="bg-blue-500 text-white px-4 py-2 rounded-md opacity-75 hover:opacity-100">
ホバーで不透明度が変わるボタン
</button>
アニメーション
<div class="opacity-0 animate-fade-in">
フェードインするテキスト
</div>
<style>
.animate-fade-in {
animation: fadeIn 1s ease-in-out forwards;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>
まとめ
TailwindCSSのopacityユーティリティクラスを使うことで、要素の透明度を簡単に制御できます。レスポンシブユーティリティクラスと組み合わせることで、画面サイズに応じて透明度を変更することもできます。オーバーレイ、ホバーエフェクト、アニメーションなど、様々なデザイン効果を実現するために、opacityを活用してみてください。
TailwindCSSにおけるrelativeとabsoluteの比較と使い方
TailwindCSSは、レスポンシブデザインを簡単に実装できるユーティリティファーストのCSSフレームワークです。lg:relativeとlg:absoluteは、どちらもレスポンシブユーティリティクラスですが、要素の配置方法が異なります。この記事では、lg:relativeとlg:absoluteの違いと使われ方を比較し、コード例を交えて解説します。
lg:relativeとlg:absoluteの違い
-
lg:relative
- 要素をドキュメントフローに従って配置しつつ、top、right、bottom、leftプロパティを使って相対的に位置を調整できる。
- 他の要素の位置に影響を与える。
-
lg:absolute
- 要素をドキュメントフローから取り除き、最も近い位置指定された祖先要素を基準に絶対的に配置する。
- 他の要素の位置に影響を与えない。
コード例と使われ方
- lg:relativeの使用例
<div class="relative lg:relative">
<div class="absolute lg:relative lg:top-0 lg:left-0 lg:mr-4">
<img src="image.jpg" alt="画像">
</div>
<div class="mt-4 lg:mt-0">
<h2>タイトル</h2>
<p>本文</p>
</div>
</div>
- 小さな画面サイズでは、画像は絶対配置され、テキストは画像の下に配置される。
- lgブレークポイント以上の画面サイズでは、画像は相対配置に変更され、テキストは画像の右側に配置される。
- lg:absoluteの使用例
<div class="relative">
<img src="background.jpg" alt="背景画像">
<div class="absolute top-0 left-0 p-4 bg-white lg:absolute lg:top-1/2 lg:left-1/2 lg:transform lg:-translate-x-1/2 lg:-translate-y-1/2">
<h2>オーバーレイテキスト</h2>
</div>
</div>
- 小さな画面サイズでは、オーバーレイテキストは背景画像の左上に絶対配置される。
- lgブレークポイント以上の画面サイズでは、オーバーレイテキストは背景画像の中央に絶対配置される。
- lg:relativeとlg:absoluteの組み合わせ例
<div class="relative">
<img src="background.jpg" alt="背景画像" class="lg:relative">
<div class="absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black lg:absolute lg:top-0 lg:left-0 lg:bottom-auto lg:right-auto lg:p-8">
<h2 class="text-white">オーバーレイタイトル</h2>
<p class="text-white">オーバーレイ本文</p>
</div>
</div>
- 小さな画面サイズでは、オーバーレイテキストは背景画像の下部に絶対配置され、背景画像の下から上へのグラデーションが適用される。
- lgブレークポイント以上の画面サイズでは、背景画像は相対配置に変更され、オーバーレイテキストは背景画像の左上に絶対配置される。
まとめ
lg:relativeとlg:absoluteは、TailwindCSSを使ってレスポンシブデザインを実装する上で非常に便利なユーティリティクラスです。lg:relativeは要素をドキュメントフローに従って配置しつつ、相対的に位置を調整できます。一方、lg:absoluteは要素をドキュメントフローから取り除き、絶対的に配置します。これらを適切に組み合わせることで、様々なレイアウトに対応できます。是非、lg:relativeとlg:absoluteを活用して、ユーザーフレンドリーなレスポンシブデザインを実現してください。
Tailwind CSS: レスポンシブブレークポイントを自在にカスタマイズする
Tailwind CSSは、デフォルトで用意されている様々な画面サイズブレイクポイントを用いて、レスポンシブなデザインを簡単に構築することができます。しかし、プロジェクトによっては、デフォルトの設定では十分でない場合があります。そんな時に役立つのが、tailwind.config.js
ファイルを用いたカスタムブレークポイントの設定です。
この高度な機能を活用することで、以下のことが可能になります。
- 独自の画面サイズブレイクポイントを定義
- 既存のブレークポイントの名前を変更
- 特定のブレークポイントを無効化
- メディアクエリを詳細に制御
本記事では、tailwind.config.js
ファイルを用いたカスタムブレークポイントの設定方法を、具体例を交えて詳しく解説します。
1. カスタムブレークポイントの設定方法
Tailwind CSSのカスタムブレークポイント設定は、tailwind.config.js
ファイル内のscreens
プロパティで行います。このプロパティには、画面サイズ名とそれに対応するメディアクエリの最小幅をキー・バリュー形式で記述します。
module.exports = {
screens: {
'sm': '640px', // デフォルト:640px
'md': '768px', // デフォルト:768px
'lg': '1024px', // デフォルト:1024px
'xl': '1280px', // デフォルト:1280px
// ここにカスタムブレークポイントを追加
}
}
例:新しいブレークポイント「ls」を追加
上記の設定に、新しいブレークポイント「ls」を追加してみましょう。このブレークポイントは、画面幅が1440px以上の場合に適用されます。
module.exports = {
screens: {
'sm': '640px',
'md': '768px',
'lg': '1024px',
'xl': '1280px',
'ls': '1440px', // 新しいブレークポイントを追加
}
}
例:既存のブレークポイントの名前を変更
既存のブレークポイントの名前を変更することも可能です。例えば、「md」を「tablet」に変更してみましょう。
module.exports = {
screens: {
'sm': '640px',
'tablet': '768px', // 'md' を 'tablet' に変更
'lg': '1024px',
'xl': '1280px',
'ls': '1440px',
}
}
例:特定のブレークポイントを無効化
特定のブレークポイントを無効化したい場合は、その画面サイズ名を省略すればOKです。例えば、「sm」ブレークポイントを無効化してみましょう。
module.exports = {
screens: {
'md': '768px',
'lg': '1024px',
'xl': '1280px',
'ls': '1440px',
}
}
2. メディアクエリを詳細に制御
screens
プロパティ以外にも、Tailwind CSSは高度なメディアクエリ制御機能を提供しています。例えば、以下の設定を用いることで、より複雑な条件に基づいてブレークポイントを適用することができます。
module.exports = {
screens: {
'sm': { min: '640px', max: '767px' }, // min: 最小幅, max: 最大幅
'md': { min: '768px', max: '1023px' },
'lg': { min: '1024px', max: '1279px' },
'xl': { min: '1280px', max: '1535px' },
'ls': { min: '1440px' },
}
}
この設定では、各ブレークポイントの最小幅と最大幅を指定しています。例えば、「md」ブレークポイントは、画面幅が768px以上1023px以下の場合に適用されます。
3. カスタムブレークポイントの注意点
カスタムブレークポイントの注意点
カスタムブレークポイントを設定する際には、以下の点に注意する必要があります。
1. デザインへの影響
ブレークポイントを変更すると、既存のデザインが崩れる可能性があります。変更後は、デザインをしっかりと確認し、必要に応じて修正を行うようにしましょう。
2. レスポンシブテスト
異なる画面サイズでデザインが正しく表示されていることを確認するために、レスポンシブテストを必ず実施しましょう。ブラウザのデベロッパーツールや、レスポンシブテストツールなどを活用するのがおすすめです。
3. チームとの共有
チームで開発している場合は、変更したブレークポイントの設定を共有し、認識を統一することが重要です。tailwind.config.js
ファイルをバージョン管理システムで管理するなど、共有しやすい方法を検討しましょう。
4. 公式ドキュメントの参照
Tailwind CSSのカスタムブレークポイント設定に関する詳細は、公式ドキュメントを参照することをおすすめします。最新の情報や、より詳細な設定方法を確認することができます。
参考情報
- Tailwind CSS ドキュメント - Screens
- Tailwind CSS 3 - レスポンシブブレークポイント [無効な URL を削除しました]
4. まとめ
Tailwind CSSのカスタムブレークポイント設定は、プロジェクトの自由度を大きく高めてくれる機能です。今回紹介した方法を参考に、ぜひ積極的に活用してみてください。
その他、役立つ情報
- Tailwind CSSには、
@media
ディレクティブを用いて、より詳細なメディアクエリを記述する方法もあります。 - カスタムブレークポイントと組み合わせて使用することで、さらに柔軟なレイアウトを実現することができます。
- Tailwind CSSコミュニティには、カスタムブレークポイントに関する情報やノウハウが豊富に共有されています。積極的に活用しましょう。
flex-1に関する詳細解説
画像には、flexboxレイアウトを使用して2列のシンプルなレイアウトを作成するコンピューターコードの一部が写っています。flex-1
クラスは2番目の列に適用され、コンテナー内の残りのスペースを占有させます。
コード詳細:
<div class="flex-container">
<div class="flex-item">最初の列</div>
<div class="flex-item flex-1">2番目の列</div>
</div>
解説:
-
div class="flex-container"
: これにより、flexboxレイアウトを使用するコンテナー要素が作成されます。.flex-container
クラスはこの要素に適用されます。 -
div class="flex-item">最初の列</div>
: レイアウトの最初の列を作成します。.flex-item
クラスはこの要素に適用され、flexboxアイテムになります。 -
div class="flex-item flex-1">2番目の列</div>
: レイアウトの2番目の列を作成します。.flex-item
クラスはこの要素に適用され、flexboxアイテムになります。さらに、flex-1
クラスも適用されます。
flex-1
クラス:
flex-1
クラスは、flexboxユーティリティクラスであり、ブラウザにこのflexboxアイテムをコンテナー内の残りのスペースを占有するように指示します。つまり、この例では、2番目の列は自動的に拡張され、flex-container
要素内の残りのスペースを埋めます。
結果:
このコードを使用すると、レイアウトは次のようになります。
[最初の列] [2番目の列]
最初の列は固定幅になり、2番目の列はコンテナー内の残りのスペースを埋めるように拡張されます。
flex-1
を使用する利点:
-
柔軟なレイアウト:
flex-1
クラスを使用して、さまざまな画面サイズやデバイスの向きに適応できる柔軟なレイアウトを作成できます。 -
使いやすい:
flex-1
クラスは、要素をコンテナー内の残りのスペースを占有させるためのシンプルで使いやすい方法です。 -
レスポンシブデザイン: flexboxレイアウトは本質的にレスポンシブであるため、さまざまな画面サイズやデバイスの向きに適応できます。
その他の考慮事項:
-
その他のflexboxプロパティ: flexboxアイテムのレイアウトを制御するために使用できるflexboxプロパティは他にもたくさんあります。たとえば、
flex-grow
、flex-shrink
、およびflex-basis
プロパティを使用して、アイテムがどのように成長、縮小、およびスペースを分配するかを制御できます。 -
ブラウザサポート: flexboxは最新のブラウザで広くサポートされていますが、比較的新しい機能です。古いブラウザをサポートする必要がある場合は、polyfillまたはフォールバックレイアウトを使用する必要がある場合があります。
結論:
flex-1
クラスは、flexboxを使用して柔軟なレイアウトを作成するための強力なツールです。使いやすい and レスポンシブなデザインを作成し、さまざまな画面サイズやデバイスの向きに適応できます。
補足:
- 上記の説明は、flexboxの基礎知識を前提としています。flexboxについて詳しく知りたい場合は、以下のリソースを参照してください。
Tailwind CSSの `transition`, `duration`, および `scale` ユーティリティを用いたアニメーション効果の実装
Tailwind CSSはアニメーションやトランジションを簡単に実装できるユーティリティクラスを提供しています。ここでは、transition
, duration
, および scale
を使って、要素にスムーズなアニメーション効果を追加する方法を詳しく説明します。
1. Transition (トランジション)
Tailwind CSSでの transition
ユーティリティは、要素のスタイル変更を時間をかけて適用することを可能にします。これにより、ユーザーインターフェースがより滑らかで自然に感じられます。
例: ボタンホバー時の色変更
<button class="bg-blue-500 text-white px-4 py-2 rounded transition">
Hover me!
</button>
2. Duration (持続時間)
duration
ユーティリティは、トランジションが完了するまでの時間を指定します。Tailwind CSSでは、様々な持続時間をクラスとして提供しており、これを利用することでアニメーションの速度を簡単に調整できます。
例: 200msで色が変わるボタン
<button class="bg-blue-500 text-white px-4 py-2 rounded transition duration-200 hover:bg-blue-700">
Hover me!
</button>
3. Scale (スケール)
scale
ユーティリティは、要素のサイズを変更するトランスフォームを適用します。このクラスは、要素を縮小または拡大する効果を持ち、インタラクティブなUI要素にダイナミックな感触を加えるのに役立ちます。
例: ホバーで拡大するカード
<div class="w-32 h-32 bg-red-500 transition duration-200 transform hover:scale-110">
Hover me!
</div>
レスポンシブデザインへの応用
Tailwind CSSでは、スクリーンサイズに応じてこれらのプロパティを適用するためのレスポンシブプレフィックスも提供しています。例えば、大きな画面でのみスケールアニメーションを適用する場合は、以下のように記述します。
例: 大画面でのみ要素を拡大
<div class="transform transition duration-300 hover:lg:scale-125">
Hover me on a large screen!
</div>
まとめ
Tailwind CSSの transition
, duration
, および scale
ユーティリティを使用することで、Webページに洗練された動きを簡単に追加できます。これらのユーティリティは、要素の動的なインタラクションを強化し、ユーザーの体験を向上させるのに非常に有効です。また、レスポンシブデザインへの対応も容易であるため、さまざまなデバイスで一貫したアニメーション効果を提供することが可能です。
補足
scale
ユーティリティを用いた効果的なアニメーション作成
Tailwind CSSの Tailwind CSSでは、scale
ユーティリティを使って要素のサイズ変更にトランジションを適用することができます。特に、scale-0
を使用すると要素が完全に縮小して見えなくなるため、あまり一般的ではないとされています。その代わりに scale-90
やその他の値を使うことで、より自然で視覚的に訴えるアニメーションを作成できます。
scale-90
が効果的か
なぜ scale-0
は要素を完全に消失させますが、これは多くのUIデザインにおいては望ましくない場合があります。完全に縮小した要素は視覚的な繋がりが失われ、ユーザーにとっては突然要素が消えたように感じられるためです。一方、scale-90
は要素を90%の大きさに縮小するだけなので、要素が完全に消えることはありません。これにより、より滑らかで自然な遷移が可能となり、ユーザーの注意を引きつつも違和感を与えにくくなります。
使用例:ボタンにスムーズなスケールダウン効果を適用
以下は、ボタンにマウスをホバーしたときに scale-90
を適用し、マウスを離したときに元のサイズ (scale-100
) に戻る例です。
<button class="bg-blue-500 text-white px-4 py-2 rounded transition duration-200 transform hover:scale-90">
Hover me!
</button>
レスポンシブデザインへの応用
Tailwind CSSのレスポンシブプレフィックスを使用することで、異なるデバイスサイズに応じて scale
ユーティリティの挙動をカスタマイズすることが可能です。例えば、タブレットやデスクトップではさらに大きく縮小させたい場合は、以下のように記述できます。
<div class="transform transition duration-300 scale-100 hover:scale-90 md:hover:scale-85">
Hover me on different devices!
</div>
まとめ
scale
ユーティリティを使用する際には、scale-0
よりも scale-90
などの値を選択することで、ユーザーにとってより自然で理解しやすいインタラクションを提供できます。このアプローチは、要素にスムーズな動きを加え、UIの全体的な魅力を向上させる効果があります。
ReactのuseEffectを使ったタイマーアラートコンポーネントの解説
このコンポーネントは、指定された秒数が経過するとアイコンを表示し、コンポーネントがアンマウントされるときにタイマーをクリアするロジックを実装しています。
コンポーネントの構造
export default function TimerAlert({
seconds = 5,
title,
body,
variant,
}: Props) {
const [hidden, setHidden] = useState(false);
useEffect(() => {
const timer = setTimeout(() => {
setHidden(true);
}, seconds * 1000)
return () => {
clearTimeout(timer)
}
}, [seconds])
return (
<div className="border p-4 rounded-lg flex items-center">
{icons[variant]}
</div>
)
}
useState
最初にuseState
フックを使ってhidden
という状態変数とその更新関数setHidden
を定義しています。この状態変数は、アイコンの表示/非表示を制御するために使用されます。初期値はfalse
になっています。
useEffect
次にuseEffect
フックを使って、タイマーロジックを実装しています。
タイマーのセットアップ
useEffect
の関数の中で、setTimeout
関数を使ってタイマーを設定しています。
const timer = setTimeout(() => {
setHidden(true);
}, seconds * 1000)
setTimeout
関数の第2引数にseconds * 1000
を渡すことで、指定された秒数(seconds
プロップス)がミリ秒に変換されています。つまり、この関数はseconds
秒後に実行されることになります。
関数の中身では、setHidden(true)
を呼び出してhidden
状態をtrue
に更新しています。これにより、アイコンが表示されることになります。
タイマークリーンアップ
useEffect
から返された関数の中で、clearTimeout(timer)
を実行しています。
return () => {
clearTimeout(timer)
}
これにより、コンポーネントがアンマウントされた時点で、タイマーをクリアできます。つまり、不要なタイマーが残らずにリソースを開放できます。
依存配列
useEffect
の第2引数に[seconds]
を渡しています。これは、seconds
プロップスが変更されたときだけ、useEffect
内の関数を再実行するようにReactに指示しています。つまり、seconds
プロップスが変更されるたびに新しいタイマーが設定され、古いタイマーがクリアされます。
戻り値
最後に、コンポーネントの戻り値ではhidden
状態に基づいてアイコンを表示しています。
<div className="border p-4 rounded-lg flex items-center">
{icons[variant]}
</div>
icons
オブジェクトからvariant
プロップスに基づいたアイコンを選択して表示しています。
コードを別途解説 + SetTimer, ClearTimerに関して
export default function TimerAlert({
seconds = 5,
title,
body,
variant,
}: Props) {
const [hidden, setHidden] = useState(false);
useEffect(() => {
const timer = setTimeout(() => {
setHidden(true);
}, seconds * 1000)
return () => {
clearTimeout(timer)
}
}, [seconds])
return (
<div className="border p-4 rounded-lg flex items-center">
{icons[variant]}
</div>
)
}
このコンポーネントでは、seconds状態が0になるとhidden状態がtrueになり、コンポーネントが非表示になります。初期状態ではsecondsが5なので、5秒後にコンポーネントが非表示になるはずです。
しかし、Resetボタンを押すとsecondsが5に戻り、再びカウントダウンが始まります。この時、以前のタイマーはキャンセルされる必要があります。そうしないと、古いタイマーが残り続け、状態を不当に変更してしまいます。
useEffectとclearTimeoutの解説
useEffectフックの中で実行される関数は、コンポーネントがマウント・更新された直後に実行されます。この関数の中でsetTimeoutを実行すると、一定時間後にsetHidden(true)が呼ばれ、コンポーネントが非表示になります。
一方、useEffectフックが返す関数は、コンポーネントがアンマウントされる直前、または次の更新の前に実行されます。つまり、この関数内でcleanup処理を行えば、useEffectで実行した副作用をキャンセルできます。
サンプルコードではclearTimeout(timer)を実行することで、setTimeoutで設定したタイマーをキャンセルしています。これにより、新しいカウントダウンが始まるたびに、古いタイマーが残ることなくコンポーネントの状態を正しく更新できます。
clearTimeoutはsetTimeoutの反対の処理を行う関数です。setTimeout(callback, delay)でタイマーをセットし、そのタイマーIDをclearTimeout(timerId)に渡すことで、そのタイマーを解除できます。
このように、useEffectでタイマーなどの副作用を実行する場合、必ずcleanup関数でそれをキャンセルする必要があります。さもないと、コンポーネントの状態が不当に変更されてしまいます。
まとめると、
useEffectの関数内で副作用(ここではsetTimeout)を実行
useEffectが返す関数内で副作用をキャンセル(ここではclearTimeout)
これにより、コンポーネントのライフサイクルに合わせて副作用を適切に実行・解除できる
初学者の方は、useEffectとclearTimeoutを使ったサンプルコードを書いてみると、その仕組みをよく理解できるはずです。
setTimeout残置の問題と危険性
ReactのuseEffectでタイマーを設定する際、setTimeout関数を使うことが多くあります。しかし、setTimeout関数で設定したタイマーをコンポーネントのアンマウント時に適切にキャンセルしないと、様々な問題が発生する可能性があります。この記事では、その問題と危険性について詳しく解説します。
setTimeout残置の具体例
次のようなコードを考えてみましょう。
import React, { useState, useEffect } from 'react';
const CountdownTimer = () => {
const [countdown, setCountdown] = useState(10);
useEffect(() => {
const timer = setTimeout(() => {
setCountdown(0);
}, countdown * 1000);
}, [countdown]);
return <div>Countdown: {countdown}</div>;
};
このコードでは、countdownステートの値が10から1ずつ減っていき、0になった時点でコンポーネントが何らかの処理を行うことを想定しています。しかし、このコードには大きな問題があります。
setTimeout関数で設定したタイマーは、明示的にキャンセルしない限り残り続けます。CountdownTimerコンポーネントでcountdownステートが10から1に変わるたびに新しいsetTimeoutが実行され、タイマーが増えていきます。
結果として、countdownが0になった時、10個のsetTimeout関数が呼び出され、10回もsetCountdown(0)が実行されてしまいます。さらに、countdownが0に到達した後も、そのコンポーネントがアンマウントされない限り、setTimeoutは実行され続けます。
setTimeout残置の危険性
上記の例が示すように、setTimeout関数で設定したタイマーを残しておくと、以下のような問題が発生する可能性があります。
1. 状態の不整合
タイマーが複数回実行されることで、コンポーネントの状態が意図しない値に変更されてしまう可能性があります。これにより、コンポーネントの動作が不安定になります。
2. メモリリーク
アンマウントされたコンポーネントに対してタイマーが実行され続けると、そのコンポーネントに関連するリソース(メモリ等)が解放されません。長期間に渡ってアプリケーションが実行され続けると、メモリリークによりパフォーマンスが低下します。
3. 予期しないサイドエフェクト
タイマーが複数回実行された結果、予期しないサイドエフェクト(データベースの更新、外部サービスへの不要な通信など)が発生する可能性があります。
このように、setTimeoutで設定したタイマーを適切にキャンセルしないと、様々な問題が発生する可能性があります。特にメモリリークは、シングルページアプリケーション(SPA)などのように長期間実行されるアプリケーションにとって、大きな脅威となります。
余談 setInterval() と setTimer()
setInterval() と setTimer() は似たような機能を持っていますが、いくつかの違いがあります。以下の表で主な類似機能と違いを比較します。
機能 | setInterval() | setTimeout() |
---|---|---|
遅延実行 | ✓ | ✓ |
繰り返し実行 | ✓ | × |
クリア関数 | clearInterval() | clearTimeout() |
引数の受け渡し | ✓ | ✓ |
スコープ | グローバルスコープ | グローバルスコープ |
setInterval() と setTimeout() の主な違いは、setInterval() が指定した間隔で繰り返し実行されるのに対し、setTimeout() は一度だけ遅延実行されることです。
使用例:
- setInterval() - 一定間隔でメッセージを表示する
let count = 0;
const intervalId = setInterval(() => {
console.log(`${count}秒経過しました。`);
count++;
if (count > 5) {
clearInterval(intervalId);
}
}, 1000);
- setTimeout() - 3秒後にアラートを表示する
setTimeout(() => {
alert("3秒経過しました。");
}, 3000);
- setTimeout() を使って setInterval() と同様の繰り返し実行を実現する
let count = 0;
function repeatMessage() {
console.log(`${count}秒経過しました。`);
count++;
if (count <= 5) {
setTimeout(repeatMessage, 1000);
}
}
setTimeout(repeatMessage, 1000);
これらの例から分かるように、setInterval() と setTimeout() は似たような機能を持っていますが、用途に応じて使い分ける必要があります。一定間隔で繰り返し実行したい場合は setInterval() を、一度だけ遅延実行したい場合は setTimeout() を使用します。また、setTimeout() を再帰的に呼び出すことで、setInterval() と同様の繰り返し実行を実現することもできます。
ReactのuseEffectについての勉強
Reactの useEffect
は、その便利さにもかかわらず、実行タイミングや依存配列の扱いが理解しにくいことから、しばしば誤用されるフックです。この記事では、useEffect
の根本的なコンセプトとライフサイクルを詳しく、実用的なコード例を交えて解説し、一般的な誤解を解消します。
依存配列の意味を正しく理解する
依存配列なしのEffect
依存配列を省略した場合、コンポーネントが再レンダリングされるたびに useEffect
のコールバックが実行されます。これは、状態やプロップスの変更があるたびに何かを実行したい場合に便利です。
useEffect(() => {
console.log('コンポーネントがレンダリングされるたびに呼び出されます');
});
依存配列ありのEffect
依存配列がある場合、配列内の値が変わったときだけ useEffect
が発火します。これにより、特定の値の更新に応じて処理を行いたい場合に非常に有効です。
const [count, setCount] = useState(0);
useEffect(() => {
console.log('countが更新されたときのみこのEffectは発火します', count);
}, [count]);
Effectのライフサイクルの具体的な理解
- 初回レンダリング時: コンポーネントがマウントされると、セットアップ関数が実行されます。
-
再レンダリング時:
- まず、クリーンアップ関数(前回のEffectで定義されている場合)が実行されます。
- 次に新しいセットアップ関数が実行されます。
- アンマウント時: コンポーネントがアンマウントされるとき、最後にクリーンアップ関数が実行されます。
useEffect(() => {
const timer = setInterval(() => {
console.log('タイマー実行中...');
}, 1000);
return () => {
clearInterval(timer);
console.log('クリーンアップ: タイマーを停止します');
};
}, []);
依存配列の正しい扱い方
Effectの関数内で参照しているすべての変数(stateやprops)は、依存配列に含めるべきです。これにより、参照している値が更新されたときのみEffectが再評価され、予期しないバグを防ぐことができます。
const [name, setName] = useState('');
useEffect(() => {
document.title = `こんにちは、${name}さん`;
}, [name]); // nameが変わるたびに実行
↓もっとドキュメント寄りの解説
依存配列の意味を正しく理解する
依存配列を省略した場合は、レンダリングのたびにEffectを発火する
依存配列がある場合は、指定した値が変わったときだけEffectを発火する
つまり、依存配列の有無の違いは「適切に間引く/間引かない」だけです。ややこしく考えすぎる必要はありません。
Effectのライフサイクル
- 初回レンダリング(マウント)時: Effectのセットアップ関数が実行される
-
再レンダリング時:
- まずクリーンアップ関数が実行される
- 次にセットアップ関数が実行される
- アンマウント時: 最後にクリーンアップ関数が実行される
Effectは、このセットアップとクリーンアップのサイクルを繰り返すだけです。ストリクトモードではマウント直後に2回セットアップ関数が呼ばれますが、概念は変わりません。
依存配列は機械的に"全て列挙する"
- Effectの関数内でreactiveな値を使っていない場合、依存配列は空にする
- reactiveな値を使っている場合、それらを全て依存配列に列挙する
このルールに従えば、ESLintを使ってチェックさせるだけで正しい依存配列を機械的に設定できます。
Reactは、できる限りEffectを確実に実行しようとします。不要な実行があっても構造的な問題はありませんが、パフォーマンスに影響があればReact.memo
などで対処します。
以上がuseEffectの主要な仕様の解説です。公式ドキュメントにもさらに詳しい情報がありますので、そちらも参照するとuseEffectをマスターできるでしょう。
参考にした動画