Lekcja 38
Projekt 1: responsywna karta profilu
W tym projekcie łączysz fundamenty z poprzednich lekcji w jeden kompletny komponent: semantyczną kartę profilu, która ma czytelny layout, stabilne media, dostępne akcje, responsywne zachowanie i kod gotowy do pokazania w portfolio.
Cel projektu
Celem jest zbudowanie karty profilu dla osoby z zespołu produktowego. Komponent powinien działać jako samodzielny blok UI: można go umieścić w sidebarze, sekcji zespołu, dashboardzie lub mini portfolio.
- HTML ma być semantyczny i zrozumiały bez CSS.
- CSS ma używać tokenów, logicznych odstępów i mobile-first.
- Karta ma mieć stabilny układ na 390px, 768px i szerokim desktopie.
- Akcje muszą mieć czytelne stany hover, focus i active.
- Komponent nie może powodować poziomego overflow.
Brief projektu
Zaprojektuj profil mentorki CSS Academy. Karta ma pokazać zdjęcie lub avatar, imię i rolę, krótki opis, listę kompetencji, trzy metryki oraz dwie akcje: kontakt i portfolio.
Kryteria sukcesu
Projekt końcowy ma być oceniany nie tylko po wyglądzie, ale też po jakości kodu. Ustal kryteria przed pisaniem CSS.
- Karta ma jeden blok klas, na przykład
.profile-project-card. - Avatar ma stabilny rozmiar i nie rozciąga layoutu.
- Metryki są prawdziwą listą albo grupą semantycznych elementów.
- Przyciski działają klawiaturą i mają widoczny
:focus-visible. - Układ startuje od jednej kolumny i rozszerza się dopiero wtedy, gdy treść tego potrzebuje.
- Kolory, odstępy, promienie i cienie są oparte o tokeny.
Struktura HTML
Zacznij od sensownej struktury. Karta profilu jest samodzielną treścią, więc dobrym wyborem jest article z nagłówkiem, opisem, listami i akcjami.
<article class="profile-project-card" aria-labelledby="profile-name">
<div class="profile-project-card__avatar" aria-hidden="true">AK</div>
<div class="profile-project-card__body">
<p class="profile-project-card__eyebrow">Frontend Mentor</p>
<h3 id="profile-name">Anna Kowalska</h3>
<p>Pomaga zespołom budować dostępne komponenty CSS.</p>
</div>
</article>
Najpierw upewnij się, że sama treść ma sens. Dopiero potem dodawaj layout, dekoracje i interakcje.
Tokeny i baza
Projekt końcowy powinien mieć lokalne tokeny komponentu. Dzięki temu warianty kolorystyczne i drobne korekty nie wymagają przepisywania wielu selektorów.
.profile-project-card {
--profile-bg: #ffffff;
--profile-text: #0f172a;
--profile-muted: #64748b;
--profile-border: #dbe3ef;
--profile-accent: #2563eb;
color: var(--profile-text);
background: var(--profile-bg);
border: 1px solid var(--profile-border);
}
Tokeny lokalne nie zastępują globalnego design systemu. Są mapą między globalną paletą a konkretną rolą w komponencie.
Layout mobile-first
Na małym ekranie karta powinna być pionowa. To najbezpieczniejszy fallback: avatar, treść, metryki i akcje układają się w naturalnej kolejności.
.profile-project-card {
display: grid;
gap: 1rem;
padding: clamp(1rem, 4vw, 1.5rem);
}
.profile-project-card__actions {
display: flex;
flex-wrap: wrap;
gap: .75rem;
}
Nie zaczynaj od desktopu. Jeśli wersja mobile jest stabilna, większy layout staje się tylko ulepszeniem.
Responsywność
Przełącz układ dopiero wtedy, gdy karta ma dość miejsca. W tym projekcie wystarczy jeden breakpoint albo container query, jeśli ćwiczysz nowsze podejście.
@media (min-width: 42rem) {
.profile-project-card {
grid-template-columns: auto minmax(0, 1fr);
align-items: start;
}
.profile-project-card__actions {
justify-content: flex-start;
}
}
Najważniejsze jest to, aby breakpoint wynikał z treści, nie z nazwy urządzenia.
Stany i dostępność
Karta profilu ma akcje, więc musi mieć czytelne stany interakcji. Fokus klawiatury nie może znikać, a przyciski powinny mieć wystarczająco duży obszar kliknięcia.
.profile-project-card__button {
min-height: 2.75rem;
transition: transform .18s ease, box-shadow .18s ease;
}
.profile-project-card__button:hover {
transform: translateY(-1px);
}
.profile-project-card__button:focus-visible {
outline: 3px solid #93c5fd;
outline-offset: 3px;
}
Stany wizualne są częścią jakości komponentu. Nie zostawiaj ich na koniec jako dekoracji.
Demo projektu
Poniżej znajduje się gotowy kierunek wizualny dla projektu. Karta używa stabilnego avatara, semantycznych sekcji, list kompetencji, metryk i akcji z widocznymi stanami.
Najczęstsze błędy początkujących
- Budowanie karty jako zestawu
divbez nagłówka, list i sensownej kolejności treści. - Ustawianie sztywnej szerokości, która powoduje overflow na telefonie.
- Rozciąganie avatara bez stałych proporcji albo bez kontrolowanego rozmiaru.
- Projektowanie desktop-first i ratowanie mobile przez wiele wyjątków.
- Używanie kolorów bezpośrednio w każdym elemencie zamiast tokenów komponentu.
- Brak stanów
:focus-visibledla linków i przycisków.
Zadanie projektowe
Zbuduj własną responsywną kartę profilu od zera.
- Utwórz semantyczny
articlez nagłówkiem, opisem, listą kompetencji, metrykami i akcjami. - Zdefiniuj lokalne tokeny komponentu dla tła, tekstu, tekstu pomocniczego, obramowania, akcentu i fokusu.
- Zaprojektuj avatar jako stabilny element o stałych proporcjach.
- Zacznij od pionowego layoutu mobile-first.
- Dodaj jeden breakpoint albo container query, który przełączy kartę w układ dwukolumnowy.
- Dodaj stany hover, active i focus-visible dla akcji.
- Sprawdź komponent na szerokościach 390px, 768px i 1280px.
Checklista jakości
- Karta jest czytelna bez CSS i ma poprawną kolejność treści.
- Na 390px nie ma poziomego przewijania.
- Avatar nie zmienia proporcji i nie rozpycha layoutu.
- Teksty mają rozsądne długości linii i czytelny kontrast.
- Akcje mają widoczny hover, active i focus-visible.
- Breakpoint wynika z treści, a nie z konkretnego urządzenia.
- Kod klas jest spójny, bez głębokich selektorów zależnych od strony.
- Komponent można wkleić do innej sekcji bez przepisywania CSS od zera.
Podsumowanie projektu
Responsywna karta profilu to pierwszy test łączenia wielu podstaw CSS w realny komponent. Jeśli HTML jest semantyczny, layout mobile-first, a style oparte o tokeny i dostępne stany, komponent nadaje się nie tylko do ćwiczenia, ale też do portfolio.
Kolejny krok roadmapy to projekt landing page z sekcją hero i kartami.
Przejdź do Lekcji 39