18-bo‘lim

Komponentlar amaliyoti

BEM nomlash tizimi, CSS ni tashkil qilish va tugma, forma, kartochka, modal kabi komponentlar yaratish.

🕑 11 daqiqa o‘qish 📄 493 so‘z 👁 5 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. BEM nomlash tizimi
  2. CSS faylini tashkil qilish
  3. Asosiy sozlamalar (reset)
  4. Komponent: tugma
  5. Komponent: forma
  6. Komponent: bildirishnoma
  7. Komponent: yorliqlar (tabs)
  8. Komponent: modal
  9. Yordamchi klasslar
  10. Komponent yozish qoidalari
  11. Xulosa

Loyiha o'sgani sari CSS boshqarib bo'lmas holga keladi. Buning yechimi - komponentlarga bo'lish va aniq nomlash tizimi.

BEM nomlash tizimi #

BEM = Block, Element, Modifier.

CSS
.blok { }                    /* mustaqil komponent */
.blok__element { }           /* komponent qismi */
.blok--modifikator { }       /* komponent varianti */
HTML
<article class="karta karta--mashhur">
    <img class="karta__rasm" src="..." alt="...">
    <div class="karta__tana">
        <h3 class="karta__sarlavha">Python darsligi</h3>
        <p class="karta__matn">Noldan boshlab...</p>
        <a class="karta__tugma karta__tugma--asosiy" href="...">Boshlash</a>
    </div>
</article>
.karta ← Blok: mustaqil komponent .karta__rasm Element: qism .karta__sarlavha Element: qism .karta--mashhur Modifikator: variant (asl klass bilan birga yoziladi)
Ikkita pastki chiziq element, ikkita tire modifikator
CSS
/* Blok */
.karta {
    background: var(--fon);
    border: 1px solid var(--chegara);
    border-radius: 14px;
    overflow: hidden;
}

/* Elementlar */
.karta__rasm {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
}

.karta__tana {
    padding: 1.25rem;
}

.karta__sarlavha {
    margin: 0 0 0.5rem;
    font-size: 1.15rem;
}

/* Modifikator */
.karta--mashhur {
    border-color: var(--asosiy);
    border-width: 2px;
}

.karta--gorizontal {
    display: grid;
    grid-template-columns: 180px 1fr;
}
BEM nima uchun foydali?
  1. Nom bo'yicha joyini bilasiz. .karta__sarlavha ni ko'rib, u qayerda ishlatilishini darhol tushunasiz.
  2. Ustunlik tekis. Barcha selektorlar bir xil kuchda (10 ball) - kaskad bilan urushish kerak emas.
  3. Ichma-ichlik yo'q. .karta .sarlavha span a kabi zanjirlar paydo bo'lmaydi.
  4. Nomlar to'qnashmaydi. .karta__sarlavha boshqa hech qayerga ta'sir qilmaydi.
BEM da uchraydigan xatolar
CSS
/* Yomon: ikki daraja element */
.karta__tana__sarlavha { }

/* Yaxshi: element faqat bir daraja */
.karta__sarlavha { }

/* Yomon: modifikator yolg'iz ishlatilgan */
<div class="karta--mashhur">

/* Yaxshi: asl klass bilan birga */
<div class="karta karta--mashhur">

CSS faylini tashkil qilish #

Natija
css/
├── uslub.css           <- barchasini import qiladi
├── asos/
│   ├── qayta-yozish.css     (reset)
│   ├── ozgaruvchilar.css
│   └── tipografiya.css
├── komponentlar/
│   ├── tugma.css
│   ├── karta.css
│   ├── forma.css
│   └── modal.css
└── sahifalar/
    ├── bosh.css
    └── darslik.css
CSS
/* uslub.css */
@import "asos/qayta-yozish.css";
@import "asos/ozgaruvchilar.css";
@import "asos/tipografiya.css";

@import "komponentlar/tugma.css";
@import "komponentlar/karta.css";
@import "komponentlar/forma.css";
@import "komponentlar/modal.css";

@import "sahifalar/bosh.css";
@import ishlab chiqarishda sekin

Har bir @import alohida so'rov yuboradi va ular ketma-ket yuklanadi. Kichik loyiha uchun muammo emas, lekin katta saytda barcha fayllarni bitta faylga birlashtirish (build vositasi bilan) yoki oddiygina bitta katta .css fayl yozish afzalroq.

Asosiy sozlamalar (reset) #

CSS
/* asos/qayta-yozish.css */
*, *::before, *::after {
    box-sizing: border-box;
}

* {
    margin: 0;
}

body {
    min-height: 100vh;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

img, picture, video, canvas, svg {
    display: block;
    max-width: 100%;
}

input, button, textarea, select {
    font: inherit;
    color: inherit;
}

p, h1, h2, h3, h4, h5, h6 {
    overflow-wrap: break-word;
}

ul[class], ol[class] {
    list-style: none;
    padding: 0;
}

a:not([class]) {
    text-decoration-skip-ink: auto;
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
input { font: inherit } nima uchun kerak?

Brauzerlar forma elementlariga o'z shriftini beradi - u sahifa shriftidan farq qiladi. Bu qator ularni bir xil qiladi. Eng ko'p unutiladigan qatorlardan biri.

Komponent: tugma #

CSS
.tugma {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;

    padding: 0.65rem 1.3rem;
    min-height: 44px;

    border: 1px solid transparent;
    border-radius: 8px;

    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;

    cursor: pointer;
    transition: background 0.18s, border-color 0.18s, transform 0.1s;
}

.tugma:active {
    transform: translateY(1px);
}

.tugma:focus-visible {
    outline: 2px solid var(--asosiy);
    outline-offset: 2px;
}

.tugma:disabled,
.tugma[aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
    transform: none;
}

/* Variantlar */
.tugma--asosiy {
    background: var(--asosiy);
    color: #fff;
}
.tugma--asosiy:hover:not(:disabled) {
    background: var(--asosiy-toq);
}

.tugma--ikkilamchi {
    background: #fff;
    color: var(--matn);
    border-color: var(--chegara);
}
.tugma--ikkilamchi:hover:not(:disabled) {
    background: var(--fon-yumshoq);
}

.tugma--xavfli {
    background: #fff;
    color: #dc2626;
    border-color: #fecaca;
}
.tugma--xavfli:hover:not(:disabled) {
    background: #dc2626;
    border-color: #dc2626;
    color: #fff;
}

.tugma--shaffof {
    background: transparent;
    color: var(--matn-och);
}

/* O'lchamlar */
.tugma--kichik { padding: 0.4rem 0.85rem; font-size: 0.85rem; min-height: 36px; }
.tugma--katta  { padding: 0.9rem 1.8rem; font-size: 1.05rem; min-height: 52px; }
.tugma--toliq  { display: flex; width: 100%; }
HTML
<button class="tugma tugma--asosiy">Saqlash</button>
<button class="tugma tugma--ikkilamchi">Bekor qilish</button>
<button class="tugma tugma--xavfli tugma--kichik">O'chirish</button>
<a href="#" class="tugma tugma--asosiy tugma--katta tugma--toliq">Boshlash</a>

Komponent: forma #

CSS
.maydon {
    display: grid;
    gap: 0.4rem;
    margin-bottom: 1.1rem;
}

.maydon__yorliq {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--matn);
}

.maydon__yorliq--majburiy::after {
    content: " *";
    color: #dc2626;
}

.maydon__kirish {
    width: 100%;
    padding: 0.65rem 0.85rem;
    border: 1px solid var(--chegara);
    border-radius: 8px;
    background: #fff;
    transition: border-color 0.18s, box-shadow 0.18s;
}

.maydon__kirish:focus {
    outline: none;
    border-color: var(--asosiy);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}

.maydon__kirish::placeholder {
    color: var(--matn-och);
}

.maydon__kirish:disabled {
    background: var(--fon-yumshoq);
    cursor: not-allowed;
}

.maydon__yordam {
    font-size: 0.82rem;
    color: var(--matn-och);
}

.maydon__xato {
    font-size: 0.82rem;
    color: #dc2626;
}

/* Xato holati */
.maydon--xato .maydon__kirish {
    border-color: #dc2626;
    background: #fef2f2;
}

/* Foydalanuvchi to'ldirgandan keyin tekshirish */
.maydon__kirish:not(:placeholder-shown):invalid {
    border-color: #dc2626;
}
:not(:placeholder-shown):invalid

Oddiy :invalid foydalanuvchi hali hech narsa yozmasdan ham qizil ramka ko'rsatadi - bu bezovta qiladi. Bu selektor esa faqat matn kiritilgandan keyin tekshiradi.

Komponent: bildirishnoma #

CSS
.xabar {
    display: flex;
    gap: 0.8rem;
    padding: 0.9rem 1.1rem;
    border: 1px solid;
    border-radius: 10px;
    font-size: 0.93rem;
}

.xabar__ikonka { flex: none; font-size: 1.1rem; line-height: 1.4; }
.xabar__tana   { flex: 1; }
.xabar__yopish {
    flex: none;
    background: none;
    border: none;
    cursor: pointer;
    opacity: 0.6;
    font-size: 1.2rem;
    line-height: 1;
}

.xabar--muvaffaqiyat { background: #f0fdf4; border-color: #bbf7d0; color: #14532d; }
.xabar--xato         { background: #fef2f2; border-color: #fecaca; color: #7f1d1d; }
.xabar--ogohlantirish{ background: #fffbeb; border-color: #fde68a; color: #78350f; }
.xabar--malumot      { background: #eff6ff; border-color: #bfdbfe; color: #1e3a8a; }
HTML
<div class="xabar xabar--muvaffaqiyat" role="status">
    <span class="xabar__ikonka" aria-hidden="true">&#10004;</span>
    <div class="xabar__tana">Ma'lumotlaringiz saqlandi.</div>
    <button class="xabar__yopish" aria-label="Yopish">&times;</button>
</div>

Komponent: yorliqlar (tabs) #

CSS
.yorliqlar {
    display: flex;
    gap: 0.25rem;
    border-bottom: 1px solid var(--chegara);
    overflow-x: auto;
}

.yorliqlar__element {
    padding: 0.7rem 1.1rem;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--matn-och);
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: color 0.18s, border-color 0.18s;
}

.yorliqlar__element:hover {
    color: var(--matn);
}

.yorliqlar__element[aria-selected="true"] {
    color: var(--asosiy);
    border-bottom-color: var(--asosiy);
}

Komponent: modal #

CSS
.modal-fon {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.55);
    display: grid;
    place-items: center;
    padding: 1rem;
    z-index: 1000;
}

.modal {
    position: relative;
    width: min(500px, 100%);
    max-height: 85vh;
    overflow-y: auto;
    background: var(--fon);
    border-radius: 16px;
    padding: 1.75rem;
    box-shadow: 0 24px 48px rgba(15, 23, 42, 0.25);
}

.modal__sarlavha {
    margin: 0 0 0.4rem;
    padding-right: 2rem;
    font-size: 1.25rem;
}

.modal__yopish {
    position: absolute;
    top: 1rem;
    right: 1rem;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 50%;
    background: var(--fon-yumshoq);
    cursor: pointer;
}

.modal__tugmalar {
    display: flex;
    gap: 0.6rem;
    justify-content: flex-end;
    margin-top: 1.5rem;
}
<dialog> tegi

Zamonaviy HTML da modal uchun tayyor element bor:

HTML
<dialog id="oyna" class="modal">
    <h2>Tasdiqlash</h2>
    <p>Rostdan ham o'chirmoqchimisiz?</p>
    <form method="dialog">
        <button class="tugma tugma--ikkilamchi">Bekor</button>
        <button class="tugma tugma--xavfli">O'chirish</button>
    </form>
</dialog>
JavaScript
document.getElementById("oyna").showModal();

<dialog> avtomatik ravishda: fokusni ushlab turadi, Esc bilan yopiladi va orqa fonni bloklaydi. Bularni qo'lda yozish ancha murakkab.

Yordamchi klasslar #

CSS
/* Faqat ekran o'quvchisi uchun */
.vizual-yashirin {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Matnni kesish */
.bir-satr {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.uch-satr {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Konteyner */
.orash {
    width: min(1200px, 100% - 2rem);
    margin-inline: auto;
}

/* Vizual yashirish */
.yashirin { display: none !important; }

Komponent yozish qoidalari #

QoidaSabab
Komponent o'z joyini bilmasinQayerga qo'ysangiz ham ishlasin
Tashqi margin bermangJoylashuvni ota element hal qilsin
Kenglikni belgilamangKonteyner belgilasin
Har bir variant - modifikator.tugma--katta, .tugma--xavfli
Bitta komponent - bitta faylTopish va o'zgartirish oson
CSS
/* Yomon: komponent o'z joyini biladi */
.karta {
    margin-bottom: 2rem;
    width: 300px;
    float: left;
}

/* Yaxshi: joylashuvni ota hal qiladi */
.karta {
    background: #fff;
    border-radius: 12px;
}

.kartalar {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 2rem;
}
Amaliy topshiriq
  1. komponentlar/ papkasini yarating va CSS ni fayllarga bo'ling.
  2. Reset faylini yozing (yuqoridagi namunani asos qiling).
  3. .tugma komponentini 4 ta variant va 3 ta o'lcham bilan yarating.
  4. .maydon forma komponentini xato holati bilan yozing.
  5. .xabar bildirishnomasini 4 ta turda qiling.
  6. Barcha komponentlarni bitta "namunalar sahifasi" (styleguide) da ko'rsating.
  7. BEM qoidalariga rioya qiling - hech qanday ichma-ich selektor bo'lmasin.
  8. Har bir komponentda :focus-visible va :disabled holatlari bo'lsin.

Xulosa #

  • BEM: .blok, .blok__element, .blok--modifikator.
  • BEM ustunlikni tekis saqlaydi va nomlar to'qnashuvini yo'q qiladi.
  • CSS ni asos / komponentlar / sahifalar ga bo'ling.
  • Har bir loyiha reset bilan boshlanadi; input { font: inherit } ni unutmang.
  • Komponent o'z joyini bilmasligi kerak - tashqi margin va kenglik bermang.
  • Har bir interaktiv komponentda :hover, :focus-visible, :disabled holatlari bo'lsin.
  • Modal uchun <dialog> tegini ko'rib chiqing - u ko'p ishni o'zi bajaradi.

Keyingi bo'limda saytni tezlashtirish va kirish imkoniyatini yaxshilashni o'rganamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.