20-bo‘lim

Amaliy loyiha - Portfolio sayti

Barcha bilimlarni birlashtirib, to'liq ishlaydigan moslashuvchan portfolio saytini noldan quramiz.

🕑 5 daqiqa o‘qish 📄 395 so‘z 👁 5 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Loyiha haqida
  2. Fayl tuzilmasi
  3. 1-qadam: HTML
  4. 2-qadam: CSS
  5. 3-qadam: JavaScript
  6. Sinov ro'yxati
  7. Bundan keyin nima?
  8. Yakuniy xulosa

19 ta bo'limni yakunladingiz. Endi hamma narsani bitta haqiqiy loyihada birlashtiramiz.

Loyiha haqida #

Yaratadigan portfolio sayti:

XususiyatIshlatiladigan bilim
Semantik tuzilma7-bo'lim
Moslashuvchan tarmoq13, 14-bo'lim
Qorong'i rejim16-bo'lim
Mobil menyu15-bo'lim
Aloqa formasi6-bo'lim
Komponentlar (BEM)18-bo'lim
Optimizatsiya va SEO19-bo'lim

Fayl tuzilmasi #

Natija
portfolio/
├── index.html
├── css/
│   └── uslub.css
├── js/
│   └── asosiy.js
└── rasmlar/
    ├── avatar.jpg
    ├── loyiha-1.jpg
    └── favicon.svg

1-qadam: HTML #

HTML
<!DOCTYPE html>
<html lang="uz">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Husanboy Qodirov | Frontend dasturchi</title>
    <meta name="description" content="Frontend dasturchi Husanboy Qodirovning
          portfoliosi. HTML, CSS va JavaScript bilan yaratilgan loyihalar.">

    <meta property="og:title" content="Husanboy Qodirov | Frontend dasturchi">
    <meta property="og:description" content="Portfolio va loyihalar">
    <meta property="og:type" content="website">

    <link rel="icon" href="rasmlar/favicon.svg" type="image/svg+xml">
    <link rel="stylesheet" href="css/uslub.css">
    <script src="js/asosiy.js" defer></script>
</head>
<body>

<a href="#asosiy" class="otish-havola">Asosiy mazmunga o'tish</a>

<!-- ===== SARLAVHA ===== -->
<header class="panel">
    <div class="orash panel__ichi">
        <a class="logo" href="#">DK</a>

        <button class="menyu-tugma" aria-expanded="false" aria-controls="menyu">
            <span class="menyu-tugma__chiziq"></span>
            <span class="menyu-tugma__chiziq"></span>
            <span class="menyu-tugma__chiziq"></span>
            <span class="vizual-yashirin">Menyuni ochish</span>
        </button>

        <nav class="menyu" id="menyu" aria-label="Asosiy menyu">
            <a class="menyu__havola" href="#men-haqimda">Men haqimda</a>
            <a class="menyu__havola" href="#konikmalar">Ko'nikmalar</a>
            <a class="menyu__havola" href="#loyihalar">Loyihalar</a>
            <a class="menyu__havola" href="#aloqa">Aloqa</a>

            <button class="mavzu-tugma" aria-label="Mavzuni almashtirish">
                <span aria-hidden="true">&#9790;</span>
            </button>
        </nav>
    </div>
</header>

<main id="asosiy">

    <!-- ===== QAHRAMON ===== -->
    <section class="qahramon">
        <div class="orash qahramon__ichi">
            <div class="qahramon__matn">
                <p class="qahramon__salom">Assalomu alaykum, men</p>
                <h1 class="qahramon__ism">Husanboy Qodirov</h1>
                <p class="qahramon__kasb">Frontend dasturchi &middot; Namangan</p>
                <p class="qahramon__tavsif">
                    Men foydalanuvchi uchun qulay, tez va chiroyli veb-saytlar yarataman.
                    HTML, CSS va JavaScript bilan ishlayman.
                </p>
                <div class="qahramon__tugmalar">
                    <a class="tugma tugma--asosiy tugma--katta" href="#loyihalar">
                        Loyihalarni ko'rish
                    </a>
                    <a class="tugma tugma--ikkilamchi tugma--katta" href="#aloqa">
                        Bog'lanish
                    </a>
                </div>
            </div>

            <img class="qahramon__avatar"
                 src="rasmlar/avatar.jpg"
                 alt="Husanboy Qodirovning surati"
                 width="320" height="320"
                 fetchpriority="high">
        </div>
    </section>

    <!-- ===== MEN HAQIMDA ===== -->
    <section class="bolim" id="men-haqimda">
        <div class="orash">
            <h2 class="bolim__sarlavha">Men haqimda</h2>
            <div class="matn-blok">
                <p>
                    Dasturlashni 2024-yilda o'rgana boshladim. Avval Python bilan
                    tanishdim, keyin veb dasturlashga qiziqib qoldim.
                </p>
                <p>
                    Hozirda frontend yo'nalishida ishlayman va har kuni yangi
                    narsa o'rganishga harakat qilaman.
                </p>
            </div>
        </div>
    </section>

    <!-- ===== KO'NIKMALAR ===== -->
    <section class="bolim bolim--yumshoq" id="konikmalar">
        <div class="orash">
            <h2 class="bolim__sarlavha">Ko'nikmalar</h2>

            <div class="konikmalar">
                <article class="konikma">
                    <h3 class="konikma__nom">HTML</h3>
                    <p class="konikma__tavsif">Semantik belgilash, formalar, kirish imkoniyati</p>
                    <div class="konikma__daraja">
                        <span class="konikma__chiziq" style="--daraja: 90%"></span>
                    </div>
                </article>

                <article class="konikma">
                    <h3 class="konikma__nom">CSS</h3>
                    <p class="konikma__tavsif">Flexbox, Grid, animatsiya, responsive</p>
                    <div class="konikma__daraja">
                        <span class="konikma__chiziq" style="--daraja: 85%"></span>
                    </div>
                </article>

                <article class="konikma">
                    <h3 class="konikma__nom">JavaScript</h3>
                    <p class="konikma__tavsif">DOM, hodisalar, fetch, ES6+</p>
                    <div class="konikma__daraja">
                        <span class="konikma__chiziq" style="--daraja: 70%"></span>
                    </div>
                </article>

                <article class="konikma">
                    <h3 class="konikma__nom">Git</h3>
                    <p class="konikma__tavsif">Versiya nazorati, GitHub, jamoada ishlash</p>
                    <div class="konikma__daraja">
                        <span class="konikma__chiziq" style="--daraja: 65%"></span>
                    </div>
                </article>
            </div>
        </div>
    </section>

    <!-- ===== LOYIHALAR ===== -->
    <section class="bolim" id="loyihalar">
        <div class="orash">
            <h2 class="bolim__sarlavha">Loyihalar</h2>

            <div class="loyihalar">
                <article class="loyiha">
                    <img class="loyiha__rasm" src="rasmlar/loyiha-1.jpg"
                         alt="Ob-havo ilovasi ekrani"
                         width="600" height="400" loading="lazy">
                    <div class="loyiha__tana">
                        <h3 class="loyiha__nom">Ob-havo ilovasi</h3>
                        <p class="loyiha__tavsif">
                            API dan ma'lumot olib, 5 kunlik ob-havo prognozini ko'rsatadi.
                        </p>
                        <ul class="teglar">
                            <li class="teg">HTML</li>
                            <li class="teg">CSS</li>
                            <li class="teg">JavaScript</li>
                        </ul>
                        <a class="loyiha__havola" href="#">Ko'rish</a>
                    </div>
                </article>

                <article class="loyiha">
                    <img class="loyiha__rasm" src="rasmlar/loyiha-2.jpg"
                         alt="Vazifalar ro'yxati ilovasi"
                         width="600" height="400" loading="lazy">
                    <div class="loyiha__tana">
                        <h3 class="loyiha__nom">Vazifalar ro'yxati</h3>
                        <p class="loyiha__tavsif">
                            Vazifalarni qo'shish, belgilash va saqlash imkoniyati bilan.
                        </p>
                        <ul class="teglar">
                            <li class="teg">CSS Grid</li>
                            <li class="teg">localStorage</li>
                        </ul>
                        <a class="loyiha__havola" href="#">Ko'rish</a>
                    </div>
                </article>

                <article class="loyiha">
                    <img class="loyiha__rasm" src="rasmlar/loyiha-3.jpg"
                         alt="Kalkulyator ilovasi"
                         width="600" height="400" loading="lazy">
                    <div class="loyiha__tana">
                        <h3 class="loyiha__nom">Kalkulyator</h3>
                        <p class="loyiha__tavsif">
                            Klaviatura bilan ham ishlaydigan moslashuvchan kalkulyator.
                        </p>
                        <ul class="teglar">
                            <li class="teg">Flexbox</li>
                            <li class="teg">JavaScript</li>
                        </ul>
                        <a class="loyiha__havola" href="#">Ko'rish</a>
                    </div>
                </article>
            </div>
        </div>
    </section>

    <!-- ===== ALOQA ===== -->
    <section class="bolim bolim--yumshoq" id="aloqa">
        <div class="orash orash--tor">
            <h2 class="bolim__sarlavha">Bog'lanish</h2>

            <form class="forma" action="#" method="post">
                <div class="maydon">
                    <label class="maydon__yorliq maydon__yorliq--majburiy" for="ism">Ismingiz</label>
                    <input class="maydon__kirish" type="text" id="ism" name="ism"
                           required minlength="2" placeholder="Ismingizni yozing">
                </div>

                <div class="maydon">
                    <label class="maydon__yorliq maydon__yorliq--majburiy" for="email">Email</label>
                    <input class="maydon__kirish" type="email" id="email" name="email"
                           required placeholder="[email protected]">
                    <span class="maydon__yordam">Javob shu manzilga yuboriladi</span>
                </div>

                <div class="maydon">
                    <label class="maydon__yorliq maydon__yorliq--majburiy" for="xabar">Xabar</label>
                    <textarea class="maydon__kirish" id="xabar" name="xabar" rows="5"
                              required minlength="10" placeholder="Xabaringizni yozing..."></textarea>
                </div>

                <button class="tugma tugma--asosiy tugma--toliq" type="submit">
                    Yuborish
                </button>
            </form>
        </div>
    </section>
</main>

<!-- ===== PASTKI QISM ===== -->
<footer class="past">
    <div class="orash past__ichi">
        <p>&copy; 2026 Husanboy Qodirov</p>
        <nav class="past__havolalar" aria-label="Ijtimoiy tarmoqlar">
            <a href="mailto:[email protected]">Email</a>
            <a href="https://t.me/husanboy" target="_blank" rel="noopener noreferrer">Telegram</a>
            <a href="https://github.com/husanboy" target="_blank" rel="noopener noreferrer">GitHub</a>
        </nav>
    </div>
</footer>

</body>
</html>

2-qadam: CSS #

CSS
/* ==========================================================
   1. O'ZGARUVCHILAR
   ========================================================== */
:root {
    --asosiy:        hsl(221, 83%, 53%);
    --asosiy-toq:    hsl(221, 83%, 43%);
    --asosiy-och:    hsl(221, 83%, 95%);

    --fon:           hsl(0, 0%, 100%);
    --fon-yumshoq:   hsl(210, 40%, 98%);
    --karta:         hsl(0, 0%, 100%);
    --chegara:       hsl(214, 32%, 91%);

    --sarlavha:      hsl(222, 47%, 11%);
    --matn:          hsl(215, 25%, 27%);
    --matn-och:      hsl(215, 16%, 47%);

    --radius:        14px;
    --soya:          0 1px 3px hsl(222 47% 11% / 0.08);
    --soya-katta:    0 12px 28px hsl(222 47% 11% / 0.12);
    --tezlik:        0.22s;
    --panel-balandlik: 68px;
}

[data-mavzu="qorongi"] {
    --fon:           hsl(222, 47%, 11%);
    --fon-yumshoq:   hsl(217, 33%, 17%);
    --karta:         hsl(217, 33%, 17%);
    --chegara:       hsl(215, 25%, 27%);

    --sarlavha:      hsl(210, 40%, 98%);
    --matn:          hsl(214, 32%, 80%);
    --matn-och:      hsl(215, 20%, 65%);

    --asosiy-och:    hsl(221, 40%, 22%);
    --soya:          0 1px 3px hsl(0 0% 0% / 0.3);
    --soya-katta:    0 12px 28px hsl(0 0% 0% / 0.45);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-mavzu="yorug"]) {
        --fon:         hsl(222, 47%, 11%);
        --fon-yumshoq: hsl(217, 33%, 17%);
        --karta:       hsl(217, 33%, 17%);
        --chegara:     hsl(215, 25%, 27%);
        --sarlavha:    hsl(210, 40%, 98%);
        --matn:        hsl(214, 32%, 80%);
        --matn-och:    hsl(215, 20%, 65%);
        --asosiy-och:  hsl(221, 40%, 22%);
    }
}

/* ==========================================================
   2. ASOSIY SOZLAMALAR
   ========================================================== */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--panel-balandlik) + 16px);
}

body {
    font-family: system-ui, "Segoe UI", Roboto, Arial, sans-serif;
    font-size: 1rem;
    line-height: 1.65;
    color: var(--matn);
    background: var(--fon);
    -webkit-font-smoothing: antialiased;
    transition: background var(--tezlik), color var(--tezlik);
}

img { display: block; max-width: 100%; height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }

h1, h2, h3 { color: var(--sarlavha); line-height: 1.2; }
a { color: var(--asosiy); }

:focus-visible {
    outline: 2px solid var(--asosiy);
    outline-offset: 3px;
    border-radius: 4px;
}

/* ==========================================================
   3. YORDAMCHILAR
   ========================================================== */
.orash {
    width: min(1120px, 100% - 2.5rem);
    margin-inline: auto;
}

.orash--tor { width: min(640px, 100% - 2.5rem); }

.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;
}

.otish-havola {
    position: absolute;
    top: -100px;
    left: 1rem;
    z-index: 999;
    background: var(--asosiy);
    color: #fff;
    padding: 0.7rem 1.2rem;
    border-radius: 0 0 8px 8px;
    text-decoration: none;
    transition: top var(--tezlik);
}
.otish-havola:focus { top: 0; }

/* ==========================================================
   4. TUGMA
   ========================================================== */
.tugma {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 44px;
    padding: 0.65rem 1.4rem;
    border: 1px solid transparent;
    border-radius: 10px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--tezlik), border-color var(--tezlik), transform 0.1s;
}
.tugma:active { transform: translateY(1px); }

.tugma--asosiy { background: var(--asosiy); color: #fff; }
.tugma--asosiy:hover { background: var(--asosiy-toq); }

.tugma--ikkilamchi {
    background: var(--karta);
    color: var(--matn);
    border-color: var(--chegara);
}
.tugma--ikkilamchi:hover { background: var(--fon-yumshoq); }

.tugma--katta { min-height: 52px; padding: 0.9rem 1.9rem; }
.tugma--toliq { display: flex; width: 100%; }

/* ==========================================================
   5. SARLAVHA PANELI
   ========================================================== */
.panel {
    position: sticky;
    top: 0;
    z-index: 100;
    background: color-mix(in srgb, var(--fon) 88%, transparent);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--chegara);
}

.panel__ichi {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: var(--panel-balandlik);
    gap: 1rem;
}

.logo {
    display: grid;
    place-items: center;
    width: 40px; height: 40px;
    background: var(--asosiy);
    color: #fff;
    border-radius: 10px;
    font-weight: 800;
    text-decoration: none;
}

.menyu-tugma {
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 0.6rem;
    background: none;
    border: none;
    cursor: pointer;
}
.menyu-tugma__chiziq {
    width: 22px; height: 2px;
    background: var(--sarlavha);
    border-radius: 2px;
    transition: transform var(--tezlik), opacity var(--tezlik);
}
.menyu-tugma[aria-expanded="true"] .menyu-tugma__chiziq:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
}
.menyu-tugma[aria-expanded="true"] .menyu-tugma__chiziq:nth-child(2) { opacity: 0; }
.menyu-tugma[aria-expanded="true"] .menyu-tugma__chiziq:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
}

.menyu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    flex-direction: column;
    gap: 0.25rem;
    padding: 1rem 1.25rem 1.5rem;
    background: var(--fon);
    border-bottom: 1px solid var(--chegara);
}
.menyu.ochiq { display: flex; }

.menyu__havola {
    padding: 0.7rem 0.4rem;
    color: var(--matn);
    font-weight: 500;
    text-decoration: none;
    border-radius: 8px;
}
.menyu__havola:hover { color: var(--asosiy); background: var(--asosiy-och); }

.mavzu-tugma {
    align-self: flex-start;
    width: 44px; height: 44px;
    margin-top: 0.5rem;
    background: var(--fon-yumshoq);
    border: 1px solid var(--chegara);
    border-radius: 10px;
    font-size: 1.1rem;
    cursor: pointer;
}

@media (min-width: 800px) {
    .menyu-tugma { display: none; }

    .menyu {
        display: flex;
        position: static;
        flex-direction: row;
        align-items: center;
        gap: 0.5rem;
        padding: 0;
        border: none;
        background: none;
    }

    .menyu__havola { padding: 0.5rem 0.9rem; }
    .mavzu-tugma { margin-top: 0; margin-left: 0.5rem; }
}

/* ==========================================================
   6. QAHRAMON
   ========================================================== */
.qahramon {
    padding-block: clamp(2.5rem, 9vw, 5.5rem);
    background: linear-gradient(180deg, var(--asosiy-och), var(--fon));
}

.qahramon__ichi {
    display: grid;
    gap: clamp(1.5rem, 5vw, 3rem);
    align-items: center;
}

.qahramon__salom { color: var(--matn-och); font-size: 1.05rem; }

.qahramon__ism {
    font-size: clamp(2rem, 7vw, 3.5rem);
    letter-spacing: -0.02em;
    margin-block: 0.2rem 0.4rem;
}

.qahramon__kasb {
    color: var(--asosiy);
    font-weight: 600;
    font-size: 1.1rem;
    margin-bottom: 1rem;
}

.qahramon__tavsif { max-width: 52ch; color: var(--matn-och); }

.qahramon__tugmalar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.75rem;
}

.qahramon__avatar {
    width: min(300px, 70%);
    aspect-ratio: 1;
    object-fit: cover;
    border-radius: 50%;
    justify-self: center;
    border: 6px solid var(--karta);
    box-shadow: var(--soya-katta);
}

@media (min-width: 800px) {
    .qahramon__ichi { grid-template-columns: 1fr auto; }
    .qahramon__avatar { width: 320px; }
}

/* ==========================================================
   7. BO'LIMLAR
   ========================================================== */
.bolim { padding-block: clamp(2.5rem, 8vw, 5rem); }
.bolim--yumshoq { background: var(--fon-yumshoq); }

.bolim__sarlavha {
    font-size: clamp(1.5rem, 4vw, 2.25rem);
    margin-bottom: 1.75rem;
    padding-bottom: 0.6rem;
    border-bottom: 3px solid var(--asosiy);
    display: inline-block;
}

.matn-blok { max-width: 65ch; display: grid; gap: 1rem; }

/* ==========================================================
   8. KO'NIKMALAR
   ========================================================== */
.konikmalar {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
    gap: 1.25rem;
}

.konikma {
    background: var(--karta);
    border: 1px solid var(--chegara);
    border-radius: var(--radius);
    padding: 1.4rem;
    box-shadow: var(--soya);
}

.konikma__nom { font-size: 1.15rem; margin-bottom: 0.3rem; }
.konikma__tavsif { color: var(--matn-och); font-size: 0.9rem; margin-bottom: 1rem; }

.konikma__daraja {
    height: 8px;
    background: var(--fon-yumshoq);
    border-radius: 999px;
    overflow: hidden;
}

.konikma__chiziq {
    display: block;
    height: 100%;
    width: var(--daraja);
    background: var(--asosiy);
    border-radius: 999px;
}

/* ==========================================================
   9. LOYIHALAR
   ========================================================== */
.loyihalar {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: 1.5rem;
}

.loyiha {
    display: flex;
    flex-direction: column;
    background: var(--karta);
    border: 1px solid var(--chegara);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--soya);
    transition: transform var(--tezlik), box-shadow var(--tezlik), border-color var(--tezlik);
}

.loyiha:hover {
    transform: translateY(-5px);
    box-shadow: var(--soya-katta);
    border-color: var(--asosiy);
}

.loyiha__rasm { aspect-ratio: 3 / 2; object-fit: cover; width: 100%; }

.loyiha__tana {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    flex: 1;
    padding: 1.3rem;
}

.loyiha__nom { font-size: 1.2rem; }
.loyiha__tavsif { color: var(--matn-och); font-size: 0.93rem; flex: 1; }

.teglar { display: flex; flex-wrap: wrap; gap: 0.4rem; list-style: none; padding: 0; }

.teg {
    background: var(--asosiy-och);
    color: var(--asosiy);
    padding: 0.2rem 0.7rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
}

.loyiha__havola { font-weight: 600; text-decoration: none; }
.loyiha__havola::after { content: " \2192"; transition: transform var(--tezlik); }
.loyiha:hover .loyiha__havola::after { content: " \2192"; }

/* ==========================================================
   10. FORMA
   ========================================================== */
.forma { display: grid; gap: 1.1rem; }
.maydon { display: grid; gap: 0.4rem; }

.maydon__yorliq { font-weight: 600; font-size: 0.92rem; color: var(--sarlavha); }
.maydon__yorliq--majburiy::after { content: " *"; color: #dc2626; }

.maydon__kirish {
    width: 100%;
    padding: 0.7rem 0.9rem;
    background: var(--karta);
    border: 1px solid var(--chegara);
    border-radius: 10px;
    transition: border-color var(--tezlik), box-shadow var(--tezlik);
}

.maydon__kirish:focus {
    outline: none;
    border-color: var(--asosiy);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--asosiy) 20%, transparent);
}

.maydon__kirish:not(:placeholder-shown):invalid { border-color: #dc2626; }
.maydon__yordam { font-size: 0.82rem; color: var(--matn-och); }

textarea.maydon__kirish { resize: vertical; min-height: 120px; }

/* ==========================================================
   11. PASTKI QISM
   ========================================================== */
.past {
    padding-block: 2rem;
    border-top: 1px solid var(--chegara);
    color: var(--matn-och);
    font-size: 0.9rem;
}

.past__ichi {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.past__havolalar { display: flex; gap: 1.25rem; }
.past__havolalar a { text-decoration: none; }
.past__havolalar a:hover { text-decoration: underline; }

/* ==========================================================
   12. HARAKATNI KAMAYTIRISH
   ========================================================== */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

3-qadam: JavaScript #

JavaScript
// js/asosiy.js

/* ---------- Mobil menyu ---------- */
const menyuTugma = document.querySelector(".menyu-tugma");
const menyu = document.querySelector(".menyu");

menyuTugma.addEventListener("click", () => {
    const ochiqmi = menyu.classList.toggle("ochiq");
    menyuTugma.setAttribute("aria-expanded", String(ochiqmi));
});

// Havola bosilganda menyuni yopish
menyu.querySelectorAll(".menyu__havola").forEach((havola) => {
    havola.addEventListener("click", () => {
        menyu.classList.remove("ochiq");
        menyuTugma.setAttribute("aria-expanded", "false");
    });
});

// Esc bilan yopish
document.addEventListener("keydown", (hodisa) => {
    if (hodisa.key === "Escape" && menyu.classList.contains("ochiq")) {
        menyu.classList.remove("ochiq");
        menyuTugma.setAttribute("aria-expanded", "false");
        menyuTugma.focus();
    }
});

/* ---------- Qorong'i rejim ---------- */
const mavzuTugma = document.querySelector(".mavzu-tugma");
const ildiz = document.documentElement;

// Saqlangan tanlovni tiklash
const saqlangan = localStorage.getItem("mavzu");
if (saqlangan) {
    ildiz.dataset.mavzu = saqlangan;
}

mavzuTugma.addEventListener("click", () => {
    const qorongimi = ildiz.dataset.mavzu === "qorongi";
    const yangi = qorongimi ? "yorug" : "qorongi";

    ildiz.dataset.mavzu = yangi;
    localStorage.setItem("mavzu", yangi);
    mavzuTugma.textContent = yangi === "qorongi" ? "☀" : "☾";
});

/* ---------- Forma tekshiruvi ---------- */
const forma = document.querySelector(".forma");

forma.addEventListener("submit", (hodisa) => {
    hodisa.preventDefault();

    if (!forma.checkValidity()) {
        forma.reportValidity();
        return;
    }

    // Bu yerda ma'lumot serverga yuboriladi
    alert("Rahmat! Xabaringiz qabul qilindi.");
    forma.reset();
});

Sinov ro'yxati #

Loyihani tugatgandan keyin quyidagilarni tekshiring:

NimaQanday
HTML to'g'riligivalidator.w3.org
Mobil ko'rinishDevTools qurilma rejimi
KlaviaturaTab bilan butun sahifani aylanish
Qorong'i rejimTugmani bosish + sahifani yangilash
KontrastDevTools rang tanlagichi
Tezlik va SEOLighthouse (Mobile)
Chop etishCtrl+P
Loyihani kengaytirish
  1. To'rtinchi bo'lim qo'shing: ish tajribasi yoki ta'lim (vaqt chizig'i ko'rinishida).
  2. Loyihalarga filtr qo'shing: barchasi / HTML / JavaScript (:has() yoki JS bilan).
  3. Aylantirishda paydo bo'lish animatsiyasini qo'shing (IntersectionObserver).
  4. Loyihalarni bosganda modal oynada batafsil ko'rsating (<dialog> bilan).
  5. Yuqoriga qaytish tugmasini qo'shing (aylantirilganda paydo bo'lsin).
  6. Rasmlarni WebP ga o'tkazing va srcset qo'shing.
  7. Ko'p tilli qiling: o'zbekcha va inglizcha versiya.
  8. GitHub Pages da bepul joylashtiring va havolani do'stlaringizga yuboring.

Bundan keyin nima? #

JavaScript DOM, hodisalar, fetch, async/await Freymvorklar React, Vue, Svelte Vositalar Git, npm, Vite, Figma Backend PHP, Node.js, ma'lumotlar bazasi Amaliyot O'z loyihalaringiz, ochiq kodga hissa
HTML va CSS dan keyingi yo'nalishlar
Eng muhim maslahat

Darslik o'qish - bilimning 20% i. Qolgan 80% - o'z qo'lingiz bilan yozgan kod.

Kichik loyihalardan boshlang: kalkulyator, ob-havo ilovasi, vazifalar ro'yxati. Har birida yangi muammoga duch kelasiz va aynan shu paytda haqiqiy o'rganish boshlanadi.

Va eng muhimi: yozgan kodingizni internetga joylashtiring. GitHub Pages bepul. Portfolio - bu diplomdan ko'ra ishonchli hujjat.

Yakuniy xulosa #

20 ta bo'limda siz quyidagilarni o'rgandingiz:

HTML: hujjat tuzilmasi, matn elementlari, havolalar, rasmlar, jadvallar, formalar, semantik teglar va kirish imkoniyati.

CSS: selektorlar, kaskad va ustunlik, ranglar, tipografiya, box model, display va position, Flexbox, Grid, moslashuvchan dizayn, o'zgaruvchilar, animatsiya va zamonaviy imkoniyatlar.

Amaliyot: BEM nomlash, komponentlarga bo'lish, optimizatsiya, SEO va to'liq portfolio loyihasi.

Bu bilimlar bilan siz istalgan dizaynni haqiqiy, ishlaydigan saytga aylantira olasiz.

Omad tilaymiz! Savol yoki taklifingiz bo'lsa, sahifa pastidagi tugma orqali yozing.

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.