最近、あるプロジェクトに取り組んでいます。上司は、当社の製品がさまざまなデバイスで優れたユーザー エクスペリエンスを実現できることを望んでおり、同時に人件費を節約するために、同じコード セットを使用してスタイルをさまざまな画面サイズに適応させたいと考えています。CSS フレームワークとして tailwindcss を選択したので、tailwindcss に基づいてマルチターミナル アダプティブ レイアウト ソリューションを作成できないか? いくつか調査した結果、tailwindcss のレスポンシブ ブレークポイント設定は非常に柔軟であり、ニーズを満たすことができることがわかりました。ブレークポイントツールクラスを利用すると、大量のメディアクエリcssの記述を回避でき、非常に便利です。次に、tailwindcss に基づいてマルチターミナル アダプティブ レイアウト ソリューションを作成した方法を紹介します。
レスポンシブブレークポイントの設定
以下は、tailwindcss のデフォルトの 5 つのブレークポイントです。
ブレークポイントのプレフィックス |
幅 |
css |
sm |
640ピクセル |
@media (最小幅: 640px) { ... } |
MD |
768ピクセル |
@media (最小幅: 768px) { ... } |
LG |
1024ピクセル |
@media (最小幅: 1024px) { ... } |
XL |
1280ピクセル |
@media (最小幅: 1280px) { ... } |
2XL |
1536ピクセル |
@media (最小幅: 1536px) { ... } |
tailwindcss はモバイル ファースト戦略を採用しています。つまり、プレフィックスのないツール クラスは小さな画面を対象とし、プレフィックスのあるツール クラスは大きな画面を対象としています。たとえば、text-center は小さな画面用で、md:text-center は大きな画面用です。tailwindcss の最初のブレークポイントの画面サイズは 640 ピクセルですが、実際には携帯電話の最大画面幅はわずか 480 ピクセルであるため、携帯電話用に特別なレイアウトがある場合は、ブレークポイントの追加を検討できます。
js复制代码// tailwind.config.js
module.exports = {
...,// 其他配置
theme: {
screens: {
xs: '480px',
...defaultTheme.screens,
},
},
}
上記のブレークポイントについては、デザイナーと協議の上、合意に達しており、通常、デザイナーは各ページにつき、携帯電話、タブレット、PCに適用されるレイアウトデザインを少なくとも3セット作成します。480 ピクセル未満の画面サイズは携帯電話、480 ピクセルから 1024 ピクセルはタブレット、1024 ピクセルから 1280 ピクセルは大きなパッド サイズと小さなラップトップ画面の混合領域と見なされます。1280pxより大きいものはPC用です。設計者は、任意のブレークポイントでレイアウトを変更することを選択し、きめ細かい制御で適応レイアウト効果を制御できます。
全体的なページレイアウト
設計者から提示されたレイアウトプランは以下の通りです。
携帯電話とパッド: 上部、中央、下部のレイアウト、上部と下部の高さは固定、中央は適応可能
PC側:左右レイアウト、左側が固定幅、右側がアダプティブ
効果は次のとおりです。
この効果を実現するには、最初からこのレイアウト スキームを使用する必要があります。
モバイル側ではサイドバー(Sider)を非表示にしてメインコンテンツ領域(Content)のみを表示し、PC側ではヘッダーとフッターを非表示にしてSiderを表示します。疑似コードは次のとおりです。
jsx复制代码<Layout>
<Header className="lg:hidden"></Header>
<Layout>
<Sider className="hidden lg:block" />
<Content></Content>
</Layout>
<Footer className="lg:hidden"></Footer>
</Layout>
flex を使用してローカル レイアウトを調整する
レイアウト フレームワークが完成した後、ローカル レイアウトの変更が発生します。一般的な変更としては、特定のブレークポイントの後、元の水平レイアウトを垂直レイアウトに、またはその逆に変更する必要があります。以下に示すように:
現時点では、フレックス レイアウトを使用してこれを実現できます。あなたはこれを行うことができます:
jsx复制代码<div className="flex flex-col md:flex-row">
<div className=" md:flex-1"></div>
<div className=" md:flex-1"></div>
</div>
水平方向のリスト適応にはグリッド/フレックスを使用する
一部のシナリオでは、水平リストの適応を実装する必要があります。要件は次のとおりです。
- リスト項目の数は可変で、複数行の配置をサポートします。
- 異なるブレークポイントでは、同じ行に異なる数の列が表示されます
- 同じブレークポイントでは、リストの幅が適応されます。
以下に示すように:
これは、flex+percentage を使用して実現できます。
jsx复制代码<div className="flex flex-wrap px-2">
{items.map((item) => (
<div className="shrink-0 max-w-1/2 basis-1/2 sm:max-w-1/3 sm:basis-1/3 lg:max-w-1/4 lg:basis-1/4 ..."></div>
))}
</div>
さらに、グリッド レイアウトを使用して次のことを実現することもできます。
jsx复制代码<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 ...">
{items.map((item) => (
<div></div>
))}
</div>
jsはレイアウトステータスを取得します
場合によっては、ボタンをクリックした後の現在のレイアウト状況を取得し、そのレイアウト状況に基づいて何らかの処理を行うなど、イベントコールバック内で現在のブレークポイントやレイアウト状況を取得する必要がある場合があります。
js复制代码const handleClick = () => {
if (window.innerWidth < 480) {
// do something for mobile
} else if (window.innerWidth < 1024) {
// do something for pad
} else {
// do something for pc
}
};
480 と 1024 は独自に定義したブレークポイントで、定数として保存でき、tailwindcss のブレークポイントと一致します。
しかし、この方法には問題があり、ブラウザのウィンドウサイズを調整するとブレークポイントやレイアウト条件が変更され、jsを実行すると現在のブレークポイントやレイアウト条件でなくなる可能性があります。
考えられるシナリオとしては、開発プロセス中にパッドが画面を回転させ、ブラウザのウィンドウ サイズを調整して、異なる側のデバイスをシミュレートすることが考えられますが、このとき、ウィンドウ サイズが変更されたときに現在のブレークポイントとレイアウトを再取得する必要があります。
コンテキスト プロバイダーを実装して、現在の画面幅とブレークポイント情報を提供し、ウィンドウ サイズが変更されたときにこの情報を更新できます。
jsx复制代码import React, { createContext, useState, useEffect } from "react";
const ScreenContext = createContext();
const ScreenProvider = ({ children }) => {
const [screenWidth, setScreenWidth] = useState(window.innerWidth);
const [screenBreakpoint, setScreenBreakpoint] = useState("");
useEffect(() => {
const handleResize = () => {
setScreenWidth(window.innerWidth);
if(window.innerWidth >= 1536) {
setScreenBreakpoint("2xl")
} else if(window.innerWidth >= 1280) {
setScreenBreakpoint("xl")
} else if(window.innerWidth >= 1024) {
setScreenBreakpoint("lg")
} else if(window.innerWidth >= 768) {
setScreenBreakpoint("md")
} else if(window.innerWidth >= 640) {
setScreenBreakpoint("sm")
} else if(window.innerWidth >= 480)) {
setScreenBreakpoint("xs")
}else{
setScreenBreakpoint("")
}
};
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return (
<ScreenContext.Provider value={
{ screenWidth, screenBreakpoint }}>
{children}
</ScreenContext.Provider>
);
};
const useScreen = () => {
const { screenWidth, screenBreakpoint } = useContext(ScreenContext);
return { screenWidth, screenBreakpoint };
};
export { ScreenContext, ScreenProvider, useScreen };
このようにして、任意のコンポーネントの useScreen フックを通じて現在の画面幅とブレークポイント情報を取得できます。
ただし、このソリューションには小さな欠点があり、tailwind.config.js と ScreenProvider でそれぞれ 2 つのブレークポイント情報を維持することです。tailwind.config.js でブレークポイント情報を変更する場合、ScreenProvider でもブレークポイント情報を変更する必要があります。それに応じて変更されます。
予防
- インタラクティブなデザイン
- 大きな画面の場合、ページには要素を表示するのに十分なスペースがありますが、携帯電話に適応させると、一部の領域に表示する余地がないため、通常はポップアップ ボックスを使用して非表示の領域を表示します。
- ホバーについて
- 携帯電話をクリックするとホバー効果がトリガーされ、ホバー効果をキャンセルするには別の場所をクリックする必要があるため、ホバー効果は PC 側にのみ適用する必要があります。したがって、PC でホバー効果を実装したい場合は、携帯電話ではホバー効果がありません。ボタンをクリックすると、次のことができます。
- jsxコードをコピーする
- <button className=" lg:hover:bg-blue-500"></button>
- コード分割
- ほとんどの場合、ユーザーには特定のブレークポイントの下でのみページが表示されるため、現在のブレークポイントに基づいてどのコンポーネントを読み込むかを決定できます。これにより、不必要なコードの読み込みを減らし、JS ボリュームを削減し、ページの読み込み速度を向上させることができます。たとえば、Sider のサイド ナビゲーション バー コンポーネントが lg ブレークポイントの後にのみ表示される場合、次のようにすることができます。
- jsxコードをコピーする
- const SiderMenu = React.lazy(() => import("./SiderMenu")); const App = () => { const { screenBreakpoint } = useScreen(); return ( <Layout> <Header className="lg:hidden"></Header> <Layout> <Sider className="hidden lg:block"> {["lg", "xl", "2xl"].includes( screenBreakpoint) && ( <Suspense fallback={null}> <SiderMenu /> </Suspense> )} </Sider> <Content>...</Content> </Layout> <Footer className="lg:hidden"> </フッター> </レイアウト> ); };
要約する
tailwindcss に基づくマルチターミナル アダプティブ レイアウト ソリューションにより、同じコード セットでスタイルをさまざまな画面サイズに適応させることができるため、開発コストを大幅に削減できます。ただし、これにはフロントエンド開発者とデザイナーが協力する必要があり、デザイナーは異なるブレークポイントでレイアウト デザインを提供する必要があり、フロントエンド開発者はデザイン ドラフトに基づいて異なるブレークポイントでレイアウトを実装する必要があります。このようにして、一連のコードと複数端末の適応レイアウト ソリューションを実装できます。