Mundarija (28)
- Bu darsda
- 1. Nega bu kerak?
- 2. className — asosiy yo'l
- 2.1 Oddiy CSS fayl
- 2.2 Shartli klass
- 2.3 O'z komponentingizga className uzatish
- 3. style prop — hisoblanadigan qiymatlar uchun
- 3.1 Qachon kerak
- 3.2 CSS o'zgaruvchisini React'dan berish
- 3.3 TypeScript va CSS o'zgaruvchisi
- 4. CSS Modules React'da
- 4.1 Fayl va import
- 4.2 Build natijasi
- 4.3 TypeScript va CSS Modules
- 5. Tailwind React'da
- 6. CSS-in-JS React'da
- 7. Qaysi birini tanlash
- 7.1 npm'dagi haqiqiy raqamlar
- 7.2 Jadval
- 8. Vazifalar: nega bitta global CSS
- 9. Ko'p uchraydigan xatolar
- 10. Mashqlar
- 1-mashq (oson): Klass satri
- 2-mashq (o'rta): Reyting yulduzlari
- 3-mashq (qiyin): Badge — CSS Modules va TypeScript
- 11. Real ishda
- Xulosa
- Manbalar
React'da stil berish usullari: className, style, CSS Modules va Tailwind
Qisqacha: React'da stil berishning asosiy yo'li — oddiy CSS va
className. Shartli klass satrini yasash uchun kichik yordamchi (clsxyoki o'zingizningcn) ishlatiladi.styleprop — faqat hisoblanadigan qiymatlar uchun (progress kengligi, foydalanuvchi rangi), eng yaxshisi CSS o'zgaruvchisi orqali. Komponentlar ko'payganda klass nomlari to'qnashmasligi uchun CSS Modules (Card.module.css→_card_9rwcv_1) yoki Tailwind (utility klasslar) tanlanadi — 2026 yilda yangi loyihalarning asosiy ikki yo'li. Runtime CSS-in-JS (styled-components, Emotion) eski loyihalarda ko'p, lekin Server Components bilan mos emas.
Bu darsda
classNameni shartli yasaysiz va"card false"tuzog'idan qochasiz.styleprop'ni qachon ishlatish kerakligini va CSS o'zgaruvchisini React'dan berishni bilasiz.- CSS Modules'ni React komponentida ishlatasiz va Vite build natijasini o'qiysiz.
- Tailwind React'da qanday ko'rinishini va
cn()nima uchun kerakligini tushunasiz. - CSS-in-JS'ning React'dagi o'rnini va cheklovini bilasiz.
- Loyiha uchun usul tanlay olasiz.
Oldin bilishingiz kerak: JSX I (className va style obyekti), CSS Modules, CSS-in-JS, Tailwind CSS 1.
1. Nega bu kerak?
06-qismda CSS'ni har tomonlama o'rgandik: kaskad, BEM, CSS Modules, CSS-in-JS, Tailwind. U yerda ular HTML va CSS nuqtai nazaridan edi. Bugun savol boshqa: React komponentida bu usullar qanday ko'rinadi va qaysi birini tanlash kerak?
Sardor «Bahor» menyusini komponentlarga bo'ldi: MenuCard, Badge ("Yangi" yorlig'i), CartButton. Har biri o'z CSS fayliga ega, import "./MenuCard.css" bilan ulangan. Bir kuni Badge qizil bo'lib qoldi — sababi MenuCard.css dagi .title qoidasi edi. Ikkala faylda ham .title bor ekan.
Muammo — CSS'ning tabiatida: hamma klass global. Vite import "./MenuCard.css" ni ko'rib, faylni sahifaga qo'shadi va u hamma komponentga ta'sir qiladi. Fayl komponent yonida turgani "faqat shu komponentga" degani emas. Kichik loyihada nomlash odati (BEM: .menu-card__title) yetadi. Katta jamoada esa avtomatik himoya kerak bo'ladi.
Hayotiy o'xshatish: oshxona javonidagi idishlar. Har oshpaz o'z idishiga "tuz" deb yozsa, bir-birinikini olib ketadi. Yechim — idishga oshpaz nomini ham yozish ("Sardor — tuz"). CSS Modules aynan shuni avtomatik qiladi: har klass nomiga fayl belgisini qo'shadi.
2. className — asosiy yo'l
2.1 Oddiy CSS fayl
Eng sodda va eng tez usul: CSS fayl va className. Birinchi React loyiha darsida Vite shablonida shunday edi:
import "./App.css"; // fayl butun sahifaga qo'shiladi
export function MenuCard({ name }: { name: string }) {
return <li className="menu-card">{name}</li>;
}className — JSX I darsidagidek, HTML'dagi class ning o'rni. import "./App.css" — Vite uchun "shu CSS'ni sahifaga qo'sh" degan buyruq (Vite IV: assetlar). Build'da hamma CSS fayllar bitta .css ga yig'iladi.
Bu usulning yagona himoyasi — nomlash odati. CSS metodologiyalari darsidagi BEM yoki komponent nomi prefiksi: .menu-card, .menu-card__title, .menu-card--sold-out.
2.2 Shartli klass
Klass ko'pincha holatga bog'liq: taom tugagan bo'lsa — xira, tanlangan bo'lsa — ramkali. Birinchi xayolga keladigan yozuv — satrlarni + bilan ulash. Natijani ko'rish uchun elementni chizib (JSX II dagi flushSync usuli), klassini konsolga chiqaramiz:
import { flushSync } from "react-dom";
import { createRoot } from "react-dom/client";
const soldOut = false;
const root = createRoot(document.getElementById("root"));
flushSync(() =>
root.render(
<li className={"card " + (soldOut && "sold-out")}>Osh</li>,
),
);
console.log(document.querySelector("li").className);Konsolda:
card falsesoldOut && "sold-out" — soldOut false bo'lsa, ifoda false ning o'zini qaytaradi (0 && tuzog'i bilan bir xil sabab). Satrga qo'shilganda false — "false" so'zi. JSX {false} ni chizmaydi, lekin satr birlashtirish JSX emas, oddiy JavaScript.
To'g'ri yo'llar:
import { flushSync } from "react-dom";
import { createRoot } from "react-dom/client";
// kichik yordamchi: falsy qiymatlarni tashlab, bo'sh joy bilan ulaydi
function cn(...classes) {
return classes.filter(Boolean).join(" ");
}
const soldOut = true;
const selected = false;
const root = createRoot(document.getElementById("root"));
flushSync(() =>
root.render(
<ul>
<li className={soldOut ? "card sold-out" : "card"}>Osh</li>
<li
className={cn("card", soldOut && "sold-out", selected && "x")}
>
Manti
</li>
</ul>,
),
);
for (const li of document.querySelectorAll("li")) {
console.log(JSON.stringify(li.className));
}Konsolda:
"card sold-out"
"card sold-out"- Ternary — ikki holat bo'lsa eng aniq.
cn(...)— ko'p shart bo'lsa.filter(Boolean)false,null,undefinedva""ni tashlaydi. CSS Modules darsida ko'rganclsxpaketi (2.1.1) aynan shuni qiladi, qo'shimcha ravishda obyekt shaklini ham tushunadi:clsx("card", { "sold-out": soldOut }). Loyihadanpm i clsxqilib ishlatish odat bo'lgan; bu yerda saytdagi natija oynasi tashqi paket yuklamagani uchun o'zimiz yozdik.
2.3 O'z komponentingizga className uzatish
className faqat HTML teglarida ishlaydi. <MenuCard className="wide" /> yozsangiz, React uni MenuCard ga oddiy props sifatida beradi — komponent o'zi uni ildiz elementiga qo'ymasa, hech narsa bo'lmaydi. Qayta ishlatiladigan komponentlarda odat: tashqaridan kelgan className ni o'zingiznikiga qo'shish.
import { flushSync } from "react-dom";
import { createRoot } from "react-dom/client";
function cn(...classes) {
return classes.filter(Boolean).join(" ");
}
function Button({ className, ...rest }) {
return <button className={cn("btn", className)} {...rest} />;
}
const root = createRoot(document.getElementById("root"));
flushSync(() =>
root.render(
<p>
<Button>Buyurtma</Button>
<Button className="btn-danger" disabled>
Bekor
</Button>
</p>,
),
);
console.log(document.getElementById("root").innerHTML);Konsolda:
<p><button class="btn">Buyurtma</button><button class="btn btn-danger" disabled="">Bekor</button></p>{ className, ...rest } — className ni ajratib olamiz, qolgan props (disabled, onClick, children) esa {...rest} bilan tugmaga o'tadi (Props darsidagi spread). Ota komponent joylashuvni (masalan, margin) o'zi qo'sha oladi, tugmaning asosiy ko'rinishi esa buzilmaydi. UI kutubxonalardagi deyarli har komponent shunday yozilgan.
Tekshirib ko'ring:
className={cn("card", count && "has-items")}—count0 bo'lsa, klass qanday bo'ladi?
Javob
"card". 0 && "has-items" → 0, filter(Boolean) esa 0 ni ham tashlaydi (u falsy). JSX'dagi {0 &&} tuzog'idan farqli, bu yerda xavf yo'q — lekin baribir count > 0 && deb yozish aniqroq.
3. style prop — hisoblanadigan qiymatlar uchun
3.1 Qachon kerak
JSX I darsida style obyekt ekanini ko'rgan edik: style={{ fontSize: 18 }}. Qachon ishlatiladi? Qiymat oldindan ma'lum bo'lmasa — u ma'lumotdan hisoblansa. Masalan, buyurtma tayyorlanish progressi:
import { useState } from "react";
function App() {
const [done, setDone] = useState(20);
return (
<div>
<div className="bar">
<div className="fill" style={{ width: `${done}%` }} />
</div>
<p>Tayyor: {done}%</p>
<button onClick={() => setDone(Math.min(done + 20, 100))}>
+20%
</button>
</div>
);
}Ekranda:
Tayyor: 60%
+20%Kenglik — har renderda state'dan. Rang, chegara, shrift — bular o'zgarmaydi, ular CSS faylda. style faqat o'zgaruvchan qismga.
style ning cheklovlari: unda :hover, @media, ::before yozib bo'lmaydi; u eng yuqori ustunlikka ega (klasslardan kuchli, Kaskad va specificity), shuning uchun CSS'dan qayta yozish qiyin. Hamma stilni style ga yozish — eng ko'p uchraydigan boshlovchi xatosi.
3.2 CSS o'zgaruvchisini React'dan berish
Yanada toza yo'l — style orqali faqat CSS o'zgaruvchisini berish, qolganini CSS'ga qoldirish (CSS o'zgaruvchilari 2):
import { flushSync } from "react-dom";
import { createRoot } from "react-dom/client";
const root = createRoot(document.getElementById("root"));
flushSync(() =>
root.render(
<div style={{ "--progress": "40%", width: 120, lineHeight: 1.5 }}>
Osh
</div>,
),
);
console.log(document.getElementById("root").innerHTML);Konsolda:
<div style="--progress: 40%; width: 120px; line-height: 1.5;">Osh</div>Uch qoida bir qatorda: --progress — o'zgaruvchi nomi o'zgarishsiz yoziladi (qo'shtirnoqda, chunki chiziqcha bor); 120 → 120px (React raqamga px qo'shadi); lineHeight: 1.5 — birliksiz xususiyat, px qo'shilmaydi. CSS esa o'zgaruvchini ishlatadi:
.fill {
width: var(--progress);
background: var(--rang-asosiy);
transition: width 0.3s;
}Endi transition, @media, qorong'i tema — hammasi CSS'da, React esa faqat bitta sonni beradi.
3.3 TypeScript va CSS o'zgaruvchisi
TypeScript'da shu yozuv xato beradi:
export function App() {
return <p style={{ "--progress": "40%" }}>Yuklanmoqda</p>;
}Xato:
TS2353: Object literal may only specify known properties, and '"--progress"' does not exist in type 'Properties<string | number, string & {}>'."Obyekt literalida faqat ma'lum xususiyatlar bo'lishi mumkin: --progress Properties turida yo'q." @types/react dagi CSSProperties turi hamma CSS xususiyatlarini biladi, lekin siz o'ylab topgan o'zgaruvchini bilmaydi. Ikki yo'l:
import type { CSSProperties } from "react";
// 1) bitta joyda: turni aniq aytish
const style = { "--progress": "40%" } as CSSProperties;
export function App() {
return <p style={style}>Yuklanmoqda</p>;
}Ekranda:
Yuklanmoqdaas — Type assertion darsidagi "men bilaman" va'dasi; bu yerda xavfsiz, chunki CSS o'zgaruvchisi har qanday satrni qabul qiladi. Ikkinchi yo'l — loyihada CSSProperties ga [key: \--${string}`]: string | number` qo'shish (module augmentation, Declaration merging) — ko'p o'zgaruvchi ishlatiladigan loyihada.
4. CSS Modules React'da
4.1 Fayl va import
CSS Modules darsida mexanizmni ko'rgansiz: .module.css fayldagi har klass nomi build'da noyob nomga aylanadi va JavaScript'ga obyekt bo'lib keladi. React'da u shunday ko'rinadi. src/MenuCard.module.css:
.card {
padding: 1rem;
border: 1px solid var(--border);
border-radius: 8px;
}
.title {
font-weight: 600;
}
.soldOut {
opacity: 0.5;
}src/MenuCard.tsx:
import styles from "./MenuCard.module.css";
type MenuCardProps = {
name: string;
price: number;
soldOut?: boolean;
};
export function MenuCard({
name,
price,
soldOut = false,
}: MenuCardProps) {
const className = soldOut
? `${styles.card} ${styles.soldOut}`
: styles.card;
return (
<li className={className}>
<span className={styles.title}>{name}</span> — {price} so'm
</li>
);
}Va ikkinchi komponent, xuddi shu .title nomi bilan — src/Badge.module.css:
.title {
color: #b3261e;
}Klass nomlari camelCase (soldOut) — styles.soldOut deb yozish uchun. sold-out bo'lsa, styles["sold-out"] deyish kerak bo'lardi.
4.2 Build natijasi
Birinchi React loyiha darsidagi bahor-menyu ga shu ikki fayl qo'shildi va build qilindi (Vite 8.3.4, 2026-10-13):
npx vite buildChiqishning ko'p qismi tanish (Birinchi React loyiha darsida o'qigan edik). Bu safar faqat .css bilan tugaydigan qatorga qarang:
vite v8.3.4 building client environment for production...
transforming...
✓ 21 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html 0.50 kB │ gzip: 0.32 kB
dist/assets/index-B_pD9pKH.css 1.95 kB │ gzip: 0.88 kB
dist/assets/index-_eoviQZK.js 220.48 kB │ gzip: 69.00 kB
✓ built in 172ms(Fayl nomlaridagi hash va vaqt sizda boshqa bo'ladi.) Nima bo'ldi? Ikkala .module.css fayl ham bitta index-….css ga yig'ildi (1.95 kB). Nomlar to'qnashmadimi — buni fayl ichidan ko'ramiz. CSS faylning ichida (qatorlarga bo'lib ko'rsatildi):
._title_1w8r7_1{color:#b3261e}
._card_9rwcv_1{border:1px solid var(--border);border-radius:8px;padding:1rem}
._title_9rwcv_7{font-weight:600}
._soldOut_9rwcv_11{opacity:.5}JavaScript ichida esa styles obyektlari:
{title:`_title_1w8r7_1`}
{card:`_card_9rwcv_1`,title:`_title_9rwcv_7`,soldOut:`_soldOut_9rwcv_11`}Ikkala .title endi boshqa-boshqa: _title_1w8r7_1 (Badge) va _title_9rwcv_7 (MenuCard). Nom tuzilishi: _ + asl nom + fayl yo'lidan hash + qator raqami. Sardorning qizil Badge muammosi bu yerda yo'q — to'qnashuv imkonsiz.
flowchart LR
A["MenuCard.module.css: .title"] --> V["Vite build"]
B["Badge.module.css: .title"] --> V
V --> C["_title_9rwcv_7"]
V --> D["_title_1w8r7_1"]4.3 TypeScript va CSS Modules
import styles from "./MenuCard.module.css" TypeScript'da xatosiz ishlaydi — Vite'ning vite/client turlari buni e'lon qiladi:
type CSSModuleClasses = { readonly [key: string]: string }
declare module '*.module.css' {
const classes: CSSModuleClasses
export default classes
}(node_modules/vite/client.d.ts dan.) Tur — "har qanday satr kalit". Natija: styles.titel (harf xatosi) ham tip xatosiz o'tadi. Biz tekshirib ko'rdik: Badge.tsx da styles.titel bilan tsc -b — exit 0. Ish vaqtida esa className={undefined} — klass yo'q, stil jim yo'qoladi. Aniq turlar kerak bo'lsa, har .module.css uchun .d.ts yasaydigan vositalar bor (masalan, typed-css-modules), lekin ko'p loyihalar bunga bormaydi.
Diqqat: CSS Modules faqat klass (va
@keyframes) nomlarini lokallashtiradi.li { … },h1 { … }kabi teg selektorlari.module.cssichida ham global bo'lib qoladi. Modul faylda faqat klasslar yozing.
5. Tailwind React'da
Tailwind CSS darslarida utility-first yo'lni o'rgangansiz: tayyor kichik klasslar (p-4, rounded-lg, font-semibold) HTML'da yoziladi. React'da ular className ga tushadi:
export function MenuCard({ name, soldOut }: Props) {
return (
<li
className={cn(
"rounded-lg border p-4",
soldOut && "opacity-50",
)}
>
<span className="font-semibold">{name}</span>
</li>
);
}Komponent — Tailwind'ning eng yaxshi do'sti: uzun klass ro'yxati bir marta komponentda yoziladi va qayta ishlatiladi. HTML'da har kartaga takrorlash kerak bo'lardi.
Tailwind loyihalarida cn odatda ikki paketdan yasaladi — Tailwind CSS 4 darsidagi kabi: clsx (shartlar) va tailwind-merge (to'qnashuvchi utility'lardan oxirgisini qoldiradi: cn("p-4", "p-2") → "p-2"). Versiyalar (2026-10-13, npm): tailwindcss 4.3.3, tailwind-merge 3.7.0, clsx 2.1.1. Vite + React loyihaga ulash va naqshlari — Tailwind CSS React loyihada, 19-qismda.
6. CSS-in-JS React'da
CSS-in-JS darsida runtime (styled-components, Emotion) va zero-runtime (vanilla-extract, Panda CSS, StyleX) yo'llarni o'lchab ko'rgansiz. React'da styled-components shunday ko'rinadi:
import styled from "styled-components";
const Price = styled.b`
color: ${(props) => (props.$sale ? "crimson" : "inherit")};
`;
<Price $sale>30000 so'm</Price>;Stil — komponentning o'zi, props'ga qarab o'zgaradi. Qulay, lekin uchta narxi bor (06-qismda o'lchanganlar):
- brauzerga kutubxona yuklanadi va stil ish vaqtida yasaladi;
- React Server Components bilan ishlamaydi — u faqat brauzerda ishlaydigan komponentlarda ("client components") yashaydi (Next.js — 23-qism);
- styled-components 2025-yil martidan maintenance mode da (yangi katta imkoniyatlar kutilmaydi). Hozirgi versiyasi — 6.6.0.
Zero-runtime vositalar yozuvni JS'da qoldiradi, natijani esa build'da oddiy CSS faylga chiqaradi: vanilla-extract 1.21.3, Panda CSS 2.2.0, StyleX 0.19.1 (Meta). Ular Server Components bilan mos.
7. Qaysi birini tanlash
7.1 npm'dagi haqiqiy raqamlar
Qaysi yo'l qanchalik keng tarqalganini npm yuklanishlari ko'rsatadi (bir hafta, 2026-10-05…11):
- tailwindcss137,3 mln
- clsx126,9 mln
- @emotion/reactMUI orqali ham20,8 mln
- styled-components11,1 mln
- @vanilla-extract/css2,6 mln
- @stylexjs/stylex2 mln
Manba: api.npmjs.org/downloads, 2026-10-05…2026-10-11 (o'lchandi 2026-10-13)
Raqamni to'g'ri o'qish kerak: yuklanish — foydalanuvchi soni emas. CI serverlardagi har npm ci ham sanaladi, Emotion esa MUI kabi kutubxonalar ichida avtomatik keladi. CSS Modules umuman yo'q — u alohida paket emas, Vite'ning ichida. Lekin yo'nalish aniq: Tailwind va clsx — hamma joyda, runtime CSS-in-JS — ancha orqada.
7.2 Jadval
| Usul | Qachon | Kuchli tomoni | Zaif tomoni |
|---|---|---|---|
CSS + className (BEM) |
kichik loyiha, bitta jamoa | tez, oddiy, vosita kerak emas | nom to'qnashuvi — faqat odat bilan |
| CSS Modules | o'rta va katta loyiha | lokal nomlar avtomatik, Vite'da tayyor | styles.x yozuvi, turlar zaif |
| Tailwind | yangi loyiha, dizayn tizimi | tez yozish, kichik CSS, izchillik | uzun className, o'rganish vaqti |
| Runtime CSS-in-JS | mavjud loyihalar | props'dan stil | JS narxi, RSC bilan mos emas |
| Zero-runtime CSS-in-JS | turlangan dizayn tizimi | TS turlari, oddiy CSS chiqadi | build sozlamasi murakkabroq |
style prop |
faqat dinamik qiymat | aniq va oddiy | hover/media yo'q, kuchli ustunlik |
Ko'p jamoalar ikkitasini birga ishlatadi: Tailwind yoki CSS Modules — asosiy, style + CSS o'zgaruvchilari — dinamik qiymatlar uchun.
8. Vazifalar: nega bitta global CSS
vazifalar dagi hamma stil — bitta src/vazifalar.css (172 qator, build'da 3.6 KB). React'ga o'tishda u o'zgarmadi va bu ataylab qilingan:
- Klasslar oz va umumiy:
qator(flex qator),xato,izoh,xavfli,bajarildi,ustida. Ular bir nechta komponentda bir xil ma'noda ishlatiladi — global bo'lishi to'g'ri. - Ranglar — CSS o'zgaruvchilari:
--rang-matn,--rang-asosiy,--rang-xato… qorong'i tema esalight-dark()bilan. Tema tanlovi<html data-tema>ni o'zgartiradi, React stil haqida hech narsa bilmaydi. - Shartli klass — ternary:
className={bajarildi ? "bajarildi" : undefined}(Qator.tsx),className={ustida ? "ustida" : undefined}(Import.tsx).undefined— "atribut umuman bo'lmasin" (bo'shclass=""emas). - Brauzer tekshiruvi CSS selektorlariga emas, id va
data-*ga tayanadi — klass nomlari erkin.
CSS Modules'ga o'tish mumkin, lekin bu loyihada u yangi muammo hal qilmaydi: to'qnashadigan nom yo'q. Qoida: usulni muammo uchun tanlang, moda uchun emas.
9. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
class="card false" |
"card " + (x && "on") |
ternary yoki cn/clsx |
| bir komponent stili boshqasiga tegdi | global CSS'da bir xil klass | BEM, CSS Modules yoki Tailwind |
style prop expects a mapping |
style="color: red" |
style={{ color: "red" }} |
TS2353 --progress da |
CSSProperties o'zgaruvchini bilmaydi |
as CSSProperties |
| CSS Modules klassi ishlamaydi, xato yo'q | styles.titel — harf xatosi |
nomni tekshiring (TS ushlamaydi) |
:hover ishlamaydi |
style prop'da yozilgan |
CSS faylga ko'chiring |
10. Mashqlar
Mashqlar kurs/mashqlar/17/21-stillar/ da.
1-mashq (oson): Klass satri
soldOut = true, isNew = false, count = 0 bo'lsa:
cn("card", soldOut && "sold-out", isNew && "new")→"card " + (isNew && "new")→style={{ marginTop: 10 }}DOM'da qanday atribut:style="margin-top: ;"
Yechim
cn — false larni tashlaydi: "card sold-out". Satr birlashtirish — "card false". marginTop: 10 → margin-top: 10px (raqamga px).
2-mashq (o'rta): Reyting yulduzlari
Rating komponenti: value (0–5) props'i. 5 ta <span> chizilsin, value dan kichik indeksdagilar className="star on", qolganlari "star". Konteynerga style orqali CSS o'zgaruvchisi: --filled: 60% (value * 20 foiz). App 3 baho bilan chizsin. Ekranda yulduzlar ★ belgisi. Ishora: Array.from({ length: 5 }, (_, i) => …) (Array.from), cn — «Shartli klass» bo'limidan.
Yechim
import { flushSync } from "react-dom";
import { createRoot } from "react-dom/client";
function cn(...classes) {
return classes.filter(Boolean).join(" ");
}
function Rating({ value }) {
return (
<p className="rating" style={{ "--filled": `${value * 20}%` }}>
{Array.from({ length: 5 }, (_, i) => (
<span key={i} className={cn("star", i < value && "on")}>
★
</span>
))}
</p>
);
}
const root = createRoot(document.getElementById("root"));
flushSync(() => root.render(<Rating value={3} />));
console.log(document.getElementById("root").innerHTML);Konsolda:
<p class="rating" style="--filled: 60%;"><span class="star on">★</span><span class="star on">★</span><span class="star on">★</span><span class="star">★</span><span class="star">★</span></p>CSS'da: .star.on { color: gold; } va, masalan, .rating { background: linear-gradient(90deg, gold var(--filled), #ddd 0) text; } — o'zgaruvchi bitta, chizishni CSS qiladi.
3-mashq (qiyin): Badge — CSS Modules va TypeScript
bahor-menyu loyihasida (yoki istalgan Vite + React + TS loyihada) Badge komponentini yozing: variant: "new" | "hot" | "soldOut" props'i, Badge.module.css da .badge (asos) va har variant uchun klass. Klass nomlari obyektini variant bo'yicha tanlang. npm run build qiling va CSS faylda uchala klassning noyob nomini toping. Keyin variant ga "sale" berib, tsc nima deyishini yozing.
Yechim
src/Badge.module.css:
.badge {
padding: 0 0.5em;
border-radius: 1em;
font-size: 0.8em;
}
.new {
background: #d7f5e3;
}
.hot {
background: #ffe1d6;
}
.soldOut {
background: #e5e4e7;
text-decoration: line-through;
}src/Badge.tsx:
import styles from "./Badge.module.css";
type Variant = "new" | "hot" | "soldOut";
const LABELS: Record<Variant, string> = {
new: "Yangi",
hot: "Achchiq",
soldOut: "Tugadi",
};
export function Badge({ variant }: { variant: Variant }) {
return (
<span className={`${styles.badge} ${styles[variant]}`}>
{LABELS[variant]}
</span>
);
}styles[variant] — variant nomi CSS klass nomi bilan bir xil bo'lgani uchun bitta qatorda tanlanadi. Build'dan keyin CSS'da ._badge_…, ._new_…, ._hot_…, ._soldOut_… ko'rinadi. <Badge variant="sale" /> esa TS2322: Type '"sale"' is not assignable to type 'Variant'. beradi: CSS Modules turlari zaif, lekin props turi kuchli — xatoni variant nomi ushlaydi.
11. Real ishda
- Yangi loyihalarda — ko'pincha Tailwind (shadcn/ui kabi kutubxonalar bilan, shadcn/ui — 19-qism) yoki CSS Modules. Ish e'lonlarida "Tailwind" so'zi tez-tez uchraydi.
- Mavjud loyihalarda — styled-components va Emotion hali ko'p: ularni o'qiy olish kerak. Ko'chirish (migratsiya) loyihalari ham ko'p.
- Dizayn tizimlari CSS o'zgaruvchilariga (tokenlar) tayanadi — React faqat qiymat beradi (Dizayn tizimi asoslari).
- Intervyu savollari: "React'da stil berishning qanday usullarini bilasiz?", "CSS Modules qanday ishlaydi?", "
styleprop'ning kamchiliklari?", "CSS-in-JS va Server Components muammosi?".
Xulosa
- Asosiy yo'l — CSS +
className; shartli klass — ternary yokicn/clsx, satr birlashtirishdafalsetuzog'i. style— faqat hisoblanadigan qiymat uchun; eng yaxshisi CSS o'zgaruvchisini berish (TS'daas CSSProperties).- CSS Modules —
.module.css,styles.card→_card_9rwcv_1; nom to'qnashuvi yo'q, lekin TS harf xatosini ushlamaydi. - Tailwind — komponentda bir marta yoziladigan utility klasslar;
cn=clsx+tailwind-merge. - Runtime CSS-in-JS — eski loyihalarda; Server Components bilan mos emas; zero-runtime — build'da CSS.
vazifalar— bitta global CSS va CSS o'zgaruvchilari: kichik ilova uchun yetarli.
Keyingi dars: Rasm, SVG va assetlar komponentlarda — rasmni import qilish, public papka, SVG'ni komponent sifatida ishlatish va alt, width/height.
Manbalar
- React: "Common components" —
className,style— react.dev/reference/react-dom/components/common - Vite: "Features — CSS Modules" — vite.dev/guide/features
- npm downloads API — api.npmjs.org (2026-10-05…11)
- styled-components: maintenance mode e'loni (2025-03-17) — github.com/orgs/styled-components/discussions/5568
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!