Un site responsiv se adaptează automat la lățimea ecranului: reorganizează layout-ul, redimensionează textele și imaginile și păstrează interacțiunile ușor de atins. Mai jos ai un ghid pas-cu-pas, cu exemple moderne de CSS (Flexbox, Grid, clamp(), container queries) și un șablon complet pe care îl poți folosi imediat.
Principii rapide (înainte de cod)
- Mobile-first. Scrie stilurile pentru ecran mic, apoi adaugă media queries pentru ecrane mai mari.
- Unități fluide. Folosește %, vw, rem, ch și funcții ca clamp() în loc de pixeli rigizi.
- Breakpoints după conținut, nu după device. Încearcă 48rem (~768px) pentru tabletă și 64–80rem pentru desktop, dar ajustează după cum “se rupe” layout-ul.
- Imagini responsive. max-width:100%, srcset/sizes, loading=”lazy”.
- Touch & accesibilitate. 44×44px ținte tactile, contrast bun, focus vizibil, nu bloca zoom-ul.
- Testează real. DevTools (Device Toolbar), Lighthouse, plus un telefon și o tabletă reale dacă poți.
Șablon minimal (HTML + CSS) – responsiv out of the box
Copiază într-un fișier index.html și pornește:
<!doctype html>
<html lang="ro">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Exemplu site responsiv</title>
<style>
/* 1) Baza: tipografie fluidă, reseturi utile */
*, *::before, *::after { box-sizing: border-box; }
html {
/* font-size fluidă, fără a micșora prea mult pe ecrane mici */
font-size: clamp(16px, 1.2vw + 12px, 18px);
}
body {
margin: 0;
line-height: 1.6;
font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
color: #0b0b0b;
background: #fff;
}
/* Link “sari la conținut” pentru accesibilitate */
.skip-link {
position: absolute; left: -9999px; top: auto;
}
.skip-link:focus {
left: 1rem; top: 1rem; background: #000; color: #fff; padding: .5rem 1rem; border-radius: .5rem;
}
/* 2) Container fluid + gutter adaptiv */
:root {
--wrap: 72rem; /* max-width total */
--gutter: clamp(.75rem, 2vw, 1.25rem);
--radius: 1rem;
--shadow: 0 10px 20px rgba(0,0,0,.06);
}
.container {
width: min(100% - 2*var(--gutter), var(--wrap));
margin-inline: auto;
}
img, picture, svg, video { max-width: 100%; height: auto; display: block; }
/* 3) Header simplu și flexibil */
header { border-bottom: 1px solid #eee; }
.header-inner {
display: flex; gap: var(--gutter); align-items: center;
justify-content: space-between; padding-block: .75rem;
}
nav ul {
display: flex; flex-wrap: wrap; gap: .75rem; list-style: none; margin: 0; padding: 0;
}
nav a { text-decoration: none; color: #0b0b0b; padding: .5rem .75rem; border-radius: .5rem; }
nav a:focus-visible, nav a:hover { background: #f3f3f3; outline: 2px solid transparent; }
/* 4) Hero cu text scalabil */
.hero { padding: clamp(1.5rem, 4vw, 3rem) 0; }
.hero h1 {
font-size: clamp(1.75rem, 2.5vw + 1rem, 3rem);
line-height: 1.1;
margin: 0 0 .5rem 0;
}
.hero p { max-width: 60ch; margin: 0; opacity: .85; }
/* 5) Grid de carduri – auto-fit + minmax = magie responsivă */
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
gap: clamp(.75rem, 2vw, 1.25rem);
padding-block: clamp(1rem, 3vw, 2rem);
}
.card {
background: #fff; border: 1px solid #eee; border-radius: var(--radius);
padding: 1rem; box-shadow: var(--shadow);
display: grid; gap: .5rem;
container-type: inline-size; /* activează container queries */
}
.card h3 { margin: 0; font-size: clamp(1.1rem, .8vw + 1rem, 1.35rem); }
/* 6) Butoane prietenoase cu touch */
.btn {
display: inline-block; border: 0; border-radius: .75rem;
padding: .75rem 1rem; background: #0b0b0b; color: #fff; cursor: pointer;
text-decoration: none; text-align: center; min-height: 44px; /* țintă tactilă minimă */
}
.btn:focus-visible { outline: 3px solid #9ad; outline-offset: 2px; }
.btn:hover { filter: brightness(1.05); }
/* 7) Media queries mobile-first (tabletă & desktop) pe rem, nu px */
@media (min-width: 48rem) { /* ~768px: tipic tabletă */
.header-inner { padding-block: 1rem; }
.hero { padding-block: 3rem; }
}
@media (min-width: 64rem) { /* ~1024px: desktop */
.hero { padding-block: 4rem; }
}
/* 8) Container queries: schimbă doar când cardul e suficient de lat, nu întreg ecranul */
@container (min-width: 22rem) {
.card { grid-template-columns: 1fr 2fr; align-items: start; }
.card picture { aspect-ratio: 4 / 3; border-radius: .75rem; overflow: hidden; }
}
/* 9) Înălțimi sigure pe mobil (bara de adrese) */
.full-viewport-section { min-height: 100dvh; display: grid; place-items: center; }
</style>
</head>
<body>
<a class="skip-link" href="#main">Sari la conținut</a>
<header>
<div class="container header-inner">
<strong>Brand</strong>
<nav aria-label="principal">
<ul>
<li><a href="#servicii">Servicii</a></li>
<li><a href="#portofoliu">Portofoliu</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</div>
</header>
<main id="main" class="container">
<section class="hero">
<h1>Site responsiv, simplu și rapid</h1>
<p>Un layout care se adaptează oricărui ecran, cu tipografie fluidă, imagini optimizate și componente prietenoase cu touch.</p>
<p style="margin-top:1rem"><a class="btn" href="#portofoliu">Vezi exemple</a></p>
</section>
<section id="portofoliu" class="grid">
<!-- Card 1 -->
<article class="card">
<picture>
<source type="image/avif" srcset="img/proiect1-400.avif 400w, img/proiect1-800.avif 800w" sizes="(min-width:64rem) 400px, (min-width:48rem) 50vw, 100vw">
<source type="image/webp" srcset="img/proiect1-400.webp 400w, img/proiect1-800.webp 800w" sizes="(min-width:64rem) 400px, (min-width:48rem) 50vw, 100vw">
<img src="img/proiect1-800.jpg" alt="Previzualizare Proiect 1" loading="lazy" width="800" height="600">
</picture>
<div>
<h3>Proiect 1</h3>
<p>Grid auto-fit, carduri cu container queries. Arată bine pe telefon, tabletă și desktop.</p>
<a class="btn" href="#">Detalii</a>
</div>
</article>
<!-- Card 2 -->
<article class="card">
<picture>
<img src="img/proiect2-800.jpg" alt="Previzualizare Proiect 2" loading="lazy" width="800" height="600">
</picture>
<div>
<h3>Proiect 2</h3>
<p>Imagini lazy-loaded și tipografie scalabilă cu <code>clamp()</code>.</p>
<a class="btn" href="#">Detalii</a>
</div>
</article>
<!-- Card 3 -->
<article class="card">
<picture>
<img src="img/proiect3-800.jpg" alt="Previzualizare Proiect 3" loading="lazy" width="800" height="600">
</picture>
<div>
<h3>Proiect 3</h3>
<p>Buton mare pentru touch, focus vizibil și contrast bun.</p>
<a class="btn" href="#">Detalii</a>
</div>
</article>
</section>
</main>
<footer class="container" style="padding:2rem 0; border-top:1px solid #eee; margin-top:2rem;">
<small>© <span id="year"></span> Brand. Toate drepturile rezervate.</small>
</footer>
<script>
// Mică îmbunătățire: anul curent
document.getElementById('year').textContent = new Date().getFullYear();
</script>
</body>
</html>
Ce face acest șablon
- Meta viewport corect: permite scalarea și evită zoom blocat (nu folosim user-scalable=no).
- Grid “auto-fit + minmax”: numărul de coloane se ajustează automat.
- Container queries: cardul își schimbă layout-ul când DEVINE suficient de lat (mai robust decât media queries globale).
- clamp(): tipografie fluidă între limite rezonabile.
- Imagini cu srcset/sizes, loading=”lazy”, plus AVIF/WebP ca formate moderne.
- 100dvh: înălțime corectă pe mobile, ținând cont de bara de adrese.
Breakpoints recomandate (în rem)
Pornește fără media queries. Adaugă doar când se “rupe” layout-ul:
@media (min-width: 36rem) { /* telefoane mari / mici tablete în portret */ }
@media (min-width: 48rem) { /* tablete */ }
@media (min-width: 64rem) { /* laptopuri */ }
@media (min-width: 80rem) { /* ecrane late */ }
Folosește rem ca să nu legi breakpoint-urile de densitatea pixelilor și ca să fie consistente dacă utilizatorul mărește fontul.
Tipografie responsivă în 1 linie
/* Paragrafe: între 16px și 18px, cresc ușor cu lățimea ecranului */
body { font-size: clamp(1rem, 0.6vw + 0.9rem, 1.125rem); }
/* Titluri care nu sar prea mult */
h1 { font-size: clamp(1.75rem, 2.5vw + 1rem, 3rem); }
h2 { font-size: clamp(1.5rem, 2vw + .75rem, 2.25rem); }
Imagini cu srcset/sizes (exemplu clar)
<picture> <source type="image/avif" srcset="img/foto-480.avif 480w, img/foto-800.avif 800w, img/foto-1200.avif 1200w" sizes="(min-width:64rem) 600px, (min-width:48rem) 50vw, 100vw"> <img src="img/foto-800.jpg" alt="Descriere imagine" width="800" height="600" loading="lazy" decoding="async"> </picture>
- sizes îi spune browserului ce lățime vizuală va avea imaginea; salvează trafic pe mobil.
- Pune mereu width/height pentru a preveni “layout shift”.
Container queries (modern, foarte util)
Activezi pe container:
.card { container-type: inline-size; }
@container (min-width: 22rem) {
.card { grid-template-columns: 1fr 2fr; }
}
Avantaj: componenta se adaptează acolo unde este plasată (sidebar vs. full), fără să depinzi de media queries globale.
Navigație prietenoasă cu touch (fără JS complicat)
Dacă meniul devine prea lung pe mobil, lasă linkurile să înfășoare pe rândul următor (cum e în șablon) sau folosește un <details><summary> pentru un meniu pliat, păstrând accesibilitatea.
Formulare și butoane pe mobil
- 44×44px ținte tactile; spațiere verticală suficientă.
- input { font-size: 16px; } previne zoom-ul auto pe iOS când câmpul e sub 16px.
- Folosește tipuri corecte: input[type=”email”], tel, number pentru tastaturi potrivite.
Performanță pe mobil (checklist scurt)
- Imagini: comprimă, folosește AVIF/WebP, loading=”lazy”.
- CSS: cât mai puțin, eventual critical CSS inline pentru fold-ul inițial.
- JS: evită biblioteci grele pentru layout; Flexbox/Grid rezolvă majoritatea.
- Fonturi: font-display: swap; și subseturi (WOFF2).
- Cache: Cache-Control pe assets statice; CDN când e posibil.
Greșeli frecvente
- Breakpoint-uri copiate “pentru iPhone X” & co. — leagă-le de conținut.
- Lățimi/înălțimi fixe în pixeli la carduri/imagini.
- Interacțiuni doar “hover” (pe touch nu există hover!).
- Blocarea zoom-ului cu user-scalable=no (contrar accesibilității).
- Uitarea width/height pe imagini → layout shift.
Alternativă: framework-uri
- Tailwind CSS: util pentru prototipare rapidă (utilitare grid, gap, md:, lg: etc.).
- Bootstrap: grilă solidă, componente clasice (col-, col-md-…), bun pentru echipe mixte.
Concluzie
Cheia unui site responsiv este să pornești mobile-first, să folosești layout-uri fluide (Flexbox/Grid), tipografie scalabilă cu clamp(), imagini optimizate, și — când ai componente reutilizabile — container queries. Cu șablonul de mai sus ai deja o bază modernă, accesibilă și performantă pentru telefon și tabletă.
Descoperă mai multe la MultiMedia
Abonează-te ca să primești ultimele articole prin email.





Lasă un răspuns