مقدمة إلى التنسيق في Next.js
يدعم Next.js طرق تنسيق متعددة، مما يمنحك المرونة لاختيار ما يناسب مشروعك. من CSS Modules والأنماط العامة إلى الحلول الحديثة مثل Tailwind CSS ومكتبات CSS-in-JS، يوفر Next.js دعمًا ممتازًا لجميع طرق التنسيق الشائعة مع التحسين المدمج.
ملاحظة: يقوم Next.js تلقائيًا بتحسين CSS عن طريق تصغيره في الإنتاج، وتقسيم الكود بكفاءة، وإزالة الأنماط غير المستخدمة عند استخدام طرق معينة مثل Tailwind CSS مع ميزة التنقية الخاصة به.
وحدات CSS
وحدات CSS هي النهج الموصى به للأنماط على مستوى المكون في Next.js. إنها تنشئ تلقائيًا أسماء فئات محلية النطاق، مما يمنع تعارضات الأنماط:
الاستخدام الأساسي لوحدة CSS
// styles/Button.module.css
.button {
background-color: #0070f3;
color: white;
padding: 12px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
}
.button:hover {
background-color: #0051cc;
}
.primary {
background-color: #0070f3;
}
.secondary {
background-color: #666;
}
// app/components/Button.tsx
import styles from './Button.module.css';
export default function Button({ children, variant = 'primary' }) {
return (
<button className={`${styles.button} ${styles[variant]}`}>
{children}
</button>
);
}
تكوين فئات CSS
// styles/Card.module.css
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
}
.highlighted {
composes: card;
border-color: #0070f3;
box-shadow: 0 4px 12px rgba(0, 112, 243, 0.1);
}
.large {
composes: card;
padding: 32px;
font-size: 18px;
}
أسماء الفئات الديناميكية
// app/components/Alert.tsx
import styles from './Alert.module.css';
export default function Alert({ type, message }) {
return (
<div className={styles[type]}>
{message}
</div>
);
}
نصيحة: تولد وحدات CSS أسماء فئات فريدة مثل \"Button_button__abc123\" تلقائيًا، مما يلغي تعارضات التسمية. هذا مثالي لمكتبات المكونات والتطبيقات الكبيرة.
الأنماط العامة
تنطبق الأنماط العامة على تطبيقك بالكامل:
إنشاء أنماط عامة
// app/globals.css
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--primary-color: #0070f3;
--secondary-color: #666;
--background: #ffffff;
--text-color: #000000;
--border-radius: 8px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
color: var(--text-color);
background: var(--background);
line-height: 1.6;
}
a {
color: var(--primary-color);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
h1, h2, h3, h4, h5, h6 {
margin-bottom: 1rem;
line-height: 1.2;
}
استيراد الأنماط العامة
// app/layout.tsx
import './globals.css';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
تحذير: يمكن استيراد CSS العام فقط في التخطيط الجذري (app/layout.tsx) في App Router. سيؤدي استيراد الأنماط العامة في مكونات أخرى إلى حدوث خطأ.
Tailwind CSS
Tailwind CSS هو إطار عمل CSS شائع يركز على الأدوات مع دعم ممتاز لـ Next.js:
تثبيت Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
تكوين Tailwind
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
colors: {
primary: '#0070f3',
secondary: '#666',
},
spacing: {
'128': '32rem',
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
},
},
},
plugins: [],
}
إضافة توجيهات Tailwind
// app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.btn-primary {
@apply bg-primary text-white px-6 py-3 rounded-lg hover:bg-blue-700 transition-colors;
}
.card {
@apply border border-gray-200 rounded-xl p-6 shadow-sm hover:shadow-md transition-shadow;
}
}
@layer utilities {
.text-balance {
text-wrap: balance;
}
}
استخدام فئات Tailwind
// app/components/Hero.tsx
export default function Hero() {
return (
<section className="bg-gradient-to-r from-blue-500 to-purple-600 py-20">
<div className="container mx-auto px-4">
<h1 className="text-4xl md:text-6xl font-bold text-white mb-6">
مرحبًا بك في Next.js
</h1>
<p className="text-xl text-white/90 mb-8 max-w-2xl">
ابنِ تطبيقات جاهزة للإنتاج مع React و Next.js
</p>
<button className="btn-primary">
ابدأ الآن
</button>
</div>
</section>
);
}
الفئات الشرطية مع clsx
npm install clsx
// app/components/Button.tsx
import clsx from 'clsx';
export default function Button({ variant, size, disabled, children }) {
return (
<button
className={clsx(
'font-semibold rounded-lg transition-colors',
{
'bg-blue-500 text-white hover:bg-blue-600': variant === 'primary',
'bg-gray-200 text-gray-800 hover:bg-gray-300': variant === 'secondary',
'px-4 py-2 text-sm': size === 'small',
'px-6 py-3 text-base': size === 'medium',
'px-8 py-4 text-lg': size === 'large',
'opacity-50 cursor-not-allowed': disabled,
}
)}
disabled={disabled}
>
{children}
</button>
);
}
دعم Sass
يحتوي Next.js على دعم مدمج لـ Sass:
تثبيت Sass
npm install -D sass
استخدام ملفات Sass
// styles/Button.module.scss
$primary-color: #0070f3;
$border-radius: 8px;
.button {
background-color: $primary-color;
color: white;
padding: 12px 24px;
border: none;
border-radius: $border-radius;
cursor: pointer;
&:hover {
background-color: darken($primary-color, 10%);
}
&.large {
padding: 16px 32px;
font-size: 18px;
}
&.small {
padding: 8px 16px;
font-size: 14px;
}
}
متغيرات ومخلوطات Sass
// styles/variables.scss
$colors: (
primary: #0070f3,
secondary: #666,
success: #10b981,
danger: #ef4444,
);
$breakpoints: (
sm: 640px,
md: 768px,
lg: 1024px,
xl: 1280px,
);
@mixin respond-to($breakpoint) {
@media (min-width: map-get($breakpoints, $breakpoint)) {
@content;
}
}
@mixin flex-center {
display: flex;
align-items: center;
justify-content: center;
}
// styles/Card.module.scss
@import './variables';
.card {
padding: 20px;
border-radius: 8px;
background: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
@include respond-to(md) {
padding: 32px;
}
.header {
@include flex-center;
margin-bottom: 16px;
}
.title {
color: map-get($colors, primary);
font-size: 24px;
}
}
CSS-in-JS
يدعم Next.js مكتبات CSS-in-JS الشائعة:
Styled-Components
npm install styled-components
npm install -D @types/styled-components
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
compiler: {
styledComponents: true,
},
};
module.exports = nextConfig;
// app/components/Button.tsx
'use client';
import styled from 'styled-components';
const StyledButton = styled.button<{ variant?: 'primary' | 'secondary' }>`
padding: 12px 24px;
border: none;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
transition: all 0.2s;
background-color: ${props =>
props.variant === 'primary' ? '#0070f3' : '#666'
};
color: white;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
`;
export default function Button({ children, variant = 'primary' }) {
return <StyledButton variant={variant}>{children}</StyledButton>;
}
Emotion
npm install @emotion/react @emotion/styled
// app/components/Card.tsx
'use client';
import styled from '@emotion/styled';
import { css } from '@emotion/react';
const CardContainer = styled.div`
padding: 24px;
border-radius: 12px;
background: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: box-shadow 0.2s;
&:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
`;
const titleStyle = css`
font-size: 24px;
font-weight: bold;
margin-bottom: 16px;
color: #0070f3;
`;
export default function Card({ title, children }) {
return (
<CardContainer>
<h2 css={titleStyle}>{title}</h2>
{children}
</CardContainer>
);
}
ملاحظة: تتطلب مكتبات CSS-in-JS توجيه 'use client' لأنها تحتاج إلى وقت تشغيل JavaScript. هذا يعني أنها تعمل فقط في Client Components، وليس Server Components.
الأنماط المضمنة
استخدم الأنماط المضمنة للتنسيق الديناميكي الخاص بالمكون:
// app/components/ProgressBar.tsx
export default function ProgressBar({ progress }) {
return (
<div style={{
width: '100%',
height: '20px',
backgroundColor: '#e0e0e0',
borderRadius: '10px',
overflow: 'hidden'
}}>
<div style={{
width: `${progress}%`,
height: '100%',
backgroundColor: '#0070f3',
transition: 'width 0.3s ease'
}} />
</div>
);
}
تكوين PostCSS
خصص PostCSS لمعالجة CSS المتقدمة:
// postcss.config.js
module.exports = {
plugins: {
'tailwindcss': {},
'autoprefixer': {},
'postcss-preset-env': {
stage: 3,
features: {
'nesting-rules': true,
},
},
...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {})
},
};
ميزات CSS الحديثة
يدعم Next.js ميزات CSS الحديثة مباشرة:
متغيرات CSS (الخصائص المخصصة)
// app/globals.css
:root {
--primary: #0070f3;
--secondary: #666;
--radius: 8px;
}
.button {
background: var(--primary);
border-radius: var(--radius);
}
شبكة CSS وFlexbox
// styles/Layout.module.css
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 24px;
}
.flex {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
}
استعلامات الحاوية
// styles/Card.module.css
.container {
container-type: inline-size;
}
.card {
padding: 16px;
}
@container (min-width: 400px) {
.card {
padding: 32px;
font-size: 18px;
}
}
أفضل الممارسات
1. اختر نهج التنسيق المناسب
- وحدات CSS: أنماط محددة النطاق للمكونات، الأفضل لمعظم الحالات
- Tailwind CSS: تطوير سريع، نهج يركز على الأدوات
- Sass: أنظمة تصميم معقدة، حاجة للمتغيرات/المخلوطات
- CSS-in-JS: أنماط ديناميكية، تبديل السمات
2. نظم الأنماط بشكل متسق
// هيكل جيد
app/
├── components/
│ ├── Button/
│ │ ├── Button.tsx
│ │ └── Button.module.css
│ └── Card/
│ ├── Card.tsx
│ └── Card.module.css
└── styles/
├── globals.css
└── variables.css
3. استخدم متغيرات CSS للسمات
// app/globals.css
:root {
--color-primary: #0070f3;
--color-background: #ffffff;
--color-text: #000000;
}
[data-theme="dark"] {
--color-primary: #3291ff;
--color-background: #1a1a1a;
--color-text: #ffffff;
}
4. حسّن للأداء
- استخدم وحدات CSS لتقسيم الكود التلقائي
- قم بتمكين ميزة التنقية في Tailwind لإزالة الأنماط غير المستخدمة
- قلل من استخدام @import في CSS (استخدم استيرادات Next.js بدلاً من ذلك)
- استفد من CSS-in-JS فقط عند الحاجة (Client Components)
تمرين: أنشئ نظام تنسيق كامل للوحة تحكم مع:
- أنماط عامة مع متغيرات CSS للسمات (وضع فاتح/داكن)
- وحدات CSS للأنماط الخاصة بالمكونات (الشريط الجانبي، شريط التنقل، البطاقة)
- فئات أدوات Tailwind للنماذج الأولية السريعة للتخطيط
- متغيرات Sass لنظام رموز التصميم
- تصميم متجاوب باستخدام نهج الهاتف المحمول أولاً
قم بتنفيذ مبدل سمة ينتقل بين الأوضاع الفاتحة والداكنة.
الملخص
يوفر Next.js دعمًا شاملاً للتنسيق لتطبيقات الويب الحديثة. النقاط الرئيسية:
- توفر وحدات CSS أنماط مكونات محددة النطاق وخالية من التعارضات
- تحدد الأنماط العامة رموز التصميم على مستوى التطبيق وإعادة التعيين
- يمكّن Tailwind CSS من التطوير السريع الذي يركز على الأدوات
- يضيف Sass ميزات قوية مثل المتغيرات والمخلوطات والتداخل
- يوفر CSS-in-JS (styled-components، Emotion) تنسيقًا ديناميكيًا
- تعمل الأنماط المضمنة للقيم الديناميكية الخاصة بالمكون
- يقوم Next.js تلقائيًا بتحسين وتصغير جميع CSS
- اختر نهج التنسيق بناءً على احتياجات المشروع وتفضيلات الفريق
- ميزات CSS الحديثة (المتغيرات، الشبكة، Flexbox) مدعومة بالكامل