Sari la conținut
← HTML & CSS de la zero
Progres curs 0 / 8 lecții (0%)

HTML: structura și elementele semantice

Lectură estimată: 14 minute

Estimare pentru text, la un ritm de 180 de cuvinte pe minut. Timpul pentru analizarea codului, exerciții și proiecte se adaugă separat și depinde de ritmul tău.

De la text la un document cu sens

Proiectul acestei lecții este o pagină pentru un atelier fictiv de biciclete. Cititorul trebuie să înțeleagă ce servicii există, ce informații pregătește pentru o cerere și care este limita demonstrației. Vom construi documentul înaintea aspectului. Dacă începi prin a desena dreptunghiuri, poți obține o pagină frumoasă în care titlurile nu sunt titluri și controalele nu au nume. Dacă începi prin întrebările cititorului, fiecare element HTML capătă un motiv clar.

Lucrează într-un director nou, atelier-final, separat de experimentul primei lecții. Fișierul principal va fi index.html. Păstrează exemplele vechi pentru comparație, dar nu copia în document mai multe elemente html sau body. Un document complet are propria structură; fragmentele care vin în lecțiile de CSS se adaugă în fișierul de stiluri, nu se lipesc la întâmplare după închiderea paginii. Această organizare previne erori greu de observat când browserul încearcă să repare automat marcajele.

Cum citești un element și atributele lui

În <p>Revizie de bicicletă</p>, p este numele elementului, iar textul este conținutul său. Eticheta de închidere delimitează conținutul. Un atribut se scrie în eticheta de deschidere și descrie o proprietate: în <a href="#servicii">Servicii</a>, href este destinația. Ghilimelele delimitează valoarea. În exemple folosim consecvent ghilimele duble, deși sintaxa HTML permite și alte forme în anumite situații. Consecvența face mai ușor de identificat o valoare incompletă.

Elementele void, precum img, input și meta, nu au conținut și nu primesc o etichetă de închidere. Nu scrie </input>. Bara finală din <input /> nu transformă un element obișnuit într-unul care se închide singur în HTML. De exemplu, <textarea /> nu înlocuiește perechea textarea. Separă această regulă de faptul că anumite etichete HTML pot fi omise în condiții precise. Pentru învățare scriem explicit html, head și body, fără să prezentăm omiterea lor permisă de standard drept o imposibilitate.

Elementele se pot include unele în altele, dar ordinea trebuie să păstreze structura. Într-un link poți avea un text accentuat; închizi mai întâi accentuarea și apoi linkul. Nu pune un buton în interiorul altui buton și nu construi un paragraf care conține o secțiune. Browserul poate reconstrui un DOM diferit de ceea ce sugerează indentarea sursei. Un validator și inspectorul de elemente sunt utile tocmai pentru a distinge aspectul vizibil de structura efectiv interpretată.

Head, body și titlul care identifică pagina

Head conține informații despre document, nu conținutul principal al articolului. În el declarăm UTF-8, viewportul și title. Salvează și fișierul în UTF-8; simpla prezență a etichetei nu convertește octeții unui fișier salvat în altă codificare. Viewportul permite o bază potrivită pentru afișarea pe ecrane înguste, fără să interzică mărirea paginii. Title identifică fila și ar trebui să distingă pagina de alte pagini ale aceluiași proiect.

Body conține informația și controalele cititorului. Titlul h1 din body poate semăna cu title, dar are alt rol: introduce subiectul conținutului. În acest proiect folosim un singur h1 și titluri h2 pentru secțiunile principale. Aceasta este o convenție clară pentru documentul nostru, nu o explicație completă a tuturor situațiilor permise de HTML. Nu alegem h4 doar fiindcă dimensiunea implicită pare potrivită; aspectul se ajustează prin CSS, iar nivelul se alege după ierarhie.

Împărțirea informației în zone

Antetul conține numele atelierului și navigarea. Main grupează conținutul dominant al paginii. Secțiunea de servicii are un titlu propriu; cele trei servicii au titluri subordonate. Footer identifică demonstrația. Nu fiecare cutie vizuală trebuie să devină section sau article. Un div este potrivit pentru o grupare necesară stilizării, fără o semnificație suplimentară. Article are sens pentru o unitate relativ independentă, precum descrierea unui serviciu care ar putea fi reutilizată separat.

Nav se folosește pentru un grup important de legături de navigare. Nu orice grup de linkuri trebuie încadrat într-un nav. În proiect avem un singur asemenea grup, cu un nume accesibil care îl identifică. Linkul de salt apare înaintea antetului și duce direct la main. Cititorul care folosește tastatura nu trebuie astfel să traverseze toate legăturile repetitive ca să ajungă la conținut. În faza fără CSS îl lăsăm vizibil, ceea ce permite verificarea simplă a destinației.

Laborator: documentul complet al atelierului

Salvează următorul document în index.html. Nu este necesară o imagine pentru a demonstra structura, iar acest lucru păstrează proiectul autonom. Formularul este intenționat o machetă: câmpurile pot fi completate, dar nu există un serviciu de expediere. Butonul de trimitere este dezactivat și explicația este vizibilă înaintea câmpurilor. Nu afișăm un mesaj fals de succes și nu folosim o adresă a unui serviciu extern pentru datele de exercițiu.

<!doctype html>
<html lang="ro">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Atelier demonstrativ de biciclete</title>
</head>
<body>
  <a class="salt" href="#continut">Sari la conținut</a>
  <header class="container bara">
    <a class="marca" href="index.html">Atelier demonstrativ</a>
    <nav aria-label="Navigare principală">
      <ul class="meniu">
        <li><a href="#servicii">Servicii</a></li>
        <li><a href="#intrebari">Întrebări</a></li>
        <li><a href="#contact">Cerere demonstrativă</a></li>
      </ul>
    </nav>
  </header>
  <main id="continut" class="container" tabindex="-1">
    <section class="introducere" aria-labelledby="titlu">
      <p class="eticheta">Proiect fictiv de învățare</p>
      <h1 id="titlu">Îngrijirea bicicletei începe cu o verificare clară</h1>
      <p class="proza">Aici exersezi o pagină de servicii.
        Nu există un atelier comercial și nu se preiau programări.</p>
      <a class="actiune" href="#servicii">Explorează serviciile demonstrative</a>
    </section>
    <section id="servicii" aria-labelledby="titlu-servicii">
      <h2 id="titlu-servicii">Servicii demonstrative</h2>
      <div class="grila">
        <article class="card">
          <h3>Revizie generală</h3>
          <p>Verificarea frânelor, transmisiei și stării roților.</p>
          <a href="#contact">Pregătește cererea pentru revizie</a>
        </article>
        <article class="card">
          <h3>Reglajul frânelor</h3>
          <p>Descriere didactică a verificării unui sistem de frânare.</p>
          <a href="#contact">Pregătește cererea pentru frâne</a>
        </article>
        <article class="card">
          <h3>Verificarea transmisiei</h3>
          <p>Exemplu de serviciu pentru identificarea uzurii și reglajelor.</p>
          <a href="#contact">Pregătește cererea pentru transmisie</a>
        </article>
      </div>
    </section>
    <section id="intrebari" aria-labelledby="titlu-intrebari">
      <h2 id="titlu-intrebari">Întrebări înainte de completare</h2>
      <details>
        <summary>Se poate trimite o programare?</summary>
        <p>Nu. Pagina este o demonstrație fără serviciu de expediere.</p>
      </details>
      <details>
        <summary>Ce date folosesc la exercițiu?</summary>
        <p>Folosește nume și adrese fictive, de exemplu ana@example.test.</p>
      </details>
    </section>
    <section id="contact" aria-labelledby="titlu-contact">
      <h2 id="titlu-contact">Cerere demonstrativă</h2>
      <p id="limita">Formular de exercițiu. Nu trimite și nu salvează mesaje.</p>
      <form aria-describedby="limita">
        <fieldset>
          <legend>Detaliile cererii fictive</legend>
          <div class="camp">
            <label for="nume">Nume fictiv (obligatoriu)</label>
            <input id="nume" name="nume" autocomplete="name" required>
          </div>
          <div class="camp">
            <label for="email">Email fictiv (obligatoriu)</label>
            <input id="email" name="email" type="email"
              autocomplete="email" required>
          </div>
          <div class="camp">
            <label for="mesaj">Descrierea cererii (obligatoriu)</label>
            <textarea id="mesaj" name="mesaj" rows="5" required></textarea>
          </div>
          <button type="submit" disabled>Trimitere indisponibilă în demo</button>
        </fieldset>
      </form>
    </section>
  </main>
  <footer class="container subsol">
    <p>Atelier demonstrativ — exercițiu HTML și CSS, fără activitate comercială.</p>
  </footer>
</body>
</html>

Citirea și verificarea structurii construite

Parcurge documentul în ordinea sursei. Mai întâi apare scurtătura către conținut, apoi identitatea, navigarea, introducerea, serviciile, întrebările și formularul. Aceeași ordine trebuie să rămână logică fără culori sau coloane. Clasele precum container și grila nu schimbă singure aspectul: vor fi puncte de legătură pentru CSS. Identificatorii precum servicii sunt unici și sunt folosiți de fragmentele linkurilor. O clasă poate apărea pe mai multe elemente; un id nu trebuie duplicat în același document.

În inspector, caută lista titlurilor. Rezultatul dorit este un h1, urmat de h2 pentru servicii, trei h3 pentru serviciile individuale, apoi h2 pentru întrebări și contact. Un cititor poate astfel deduce structura fără să parcurgă toate paragrafele. Modifică temporar un h3 în p și observă că textul încă există, însă nu mai este un titlu semantic. Revino apoi la h3. Această probă explică de ce mărirea vizuală a textului nu substituie elementul potrivit.

Linkul către #contact nu selectează automat serviciul și nu completează formularul. Textul lui spune că pregătești cererea, nu că ai rezervat ceva. Dacă ai nevoie de selectarea serviciului, ar trebui să adaugi un control explicit sau un comportament suplimentar, explicat separat. Proiectul evită această promisiune pentru că studiem HTML și CSS. Păstrează diferența între navigarea către o zonă și executarea unei operații asupra datelor.

Link, buton și control nativ

Un link cu href reprezintă o destinație. Un buton declanșează o acțiune, precum trimiterea unui formular. Nu înlocui linkul cu un div pe care intenționezi să îl faci clicabil mai târziu: ai pierde comportamente native de tastatură, numele rolului și posibilitatea deschiderii destinației într-o filă nouă. Un link poate arăta ca un buton prin CSS și rămâne corect dacă scopul lui este navigarea. Semantica se alege după funcție, nu după forma dreptunghiulară.

Details și summary oferă un control nativ pentru întrebările expandabile. Fără JavaScript, utilizatorul poate deschide și închide răspunsul. Apasă Tab până la prima întrebare, apoi Enter sau Space și observă starea. Nu pune încă un buton în summary și nu ascunde indicatorul fără o alternativă clară. În această etapă păstrăm comportamentul implicit, pentru a verifica funcția înainte de stilizare. Un component personalizat ar necesita mai mult cod și verificări suplimentare.

Formulare: numele câmpului și numele pentru cititor

For din label trebuie să coincidă cu id din control. Apasă pe eticheta Nume fictiv: focusul trebuie să ajungă în câmpul nume. Atributul name are alt rol, identificând câmpul în datele formularului; el nu creează singur o etichetă vizibilă. Placeholder poate oferi un exemplu scurt, dar dispare la completare și nu înlocuiește label. În proiect nu avem nevoie de placeholder pentru a explica ce se cere, fiindcă etichetele și nota introductivă sunt suficiente.

Required indică un câmp obligatoriu și participă la validarea nativă. Type email cere o sintaxă de adresă acceptată de browser, nu dovedește că adresa există sau aparține persoanei. Nicio validare din browser nu înlocuiește verificarea pe server atunci când există un serviciu real. În demonstrația noastră butonul este dezactivat, deci nu prezentăm completarea drept o trimitere. Dacă scoți disabled pentru un experiment, lucrează numai cu date fictive și înțelege că formularul fără configurare de expediere poate naviga către pagina curentă cu date în URL.

Nu modifica formularul de pe un site real ca să reproduci acel experiment. Pentru lecție este suficient să inspectezi proprietatea validity a câmpului în instrumentele browserului sau să compari un email gol, unul fără separator și unul fictiv valid. Observă că un control dezactivat este de obicei omis din navigarea cu Tab. Aceasta este intenția butonului nostru: o funcție indisponibilă nu se prezintă ca o acțiune activă. Câmpurile și întrebările rămân accesibile pentru exercițiu.

Imagini și alternative după rol

Dacă adaugi ulterior o fotografie informativă, textul alternativ trebuie să comunice informația relevantă în context. Pentru o imagine care arată poziția unei piese, descrierea acelei poziții este mai utilă decât „imagine bicicletă”. Dacă imaginea este strict decorativă și textul alăturat conține deja informația, un atribut alt gol o poate exclude din citirea redundantă. O imagine folosită ca unic conținut al unui link trebuie să dea nume destinației, nu doar să descrie culorile fotografiei.

Nu inventa o descriere detaliată pentru o imagine pe care nu ai verificat-o. Nu încărca o fotografie doar ca să umpli spațiul dintr-un card. Proiectul nostru nu are nevoie de imagini pentru a explica serviciile; această decizie elimină o dependență, nu declară imaginile inutile în general. Dacă extinzi proiectul, păstrează sursa și dreptul de folosire, definește width și height după proporțiile reale și verifică textul alternativ în contextul paginii.

Exerciții rezolvate și criterii de acceptare

Exercițiul unu: ai două câmpuri cu id="email", iar două etichete indică același id. Rezolvarea este să atribui identificatori unici și să corectezi fiecare for, apoi să apeși pe fiecare etichetă și să verifici controlul focalizat. Schimbarea culorii bordurii nu repară asocierea. Într-un formular lung, acest defect poate fi greu de observat vizual, motiv pentru care controlul identificatorilor face parte din verificarea structurii, înaintea stilurilor.

Exercițiul doi: serviciile trebuie să apară într-un cuprins al paginii, dar sunt paragrafe îngroșate. Înlocuiește marcajul cu h3 în interiorul secțiunii Servicii, păstrând textul. Ajustează ulterior dimensiunea în CSS. Rezultatul corect este o ierarhie coerentă, nu obligativitatea unui anumit font. Citește numai titlurile cu voce tare: ar trebui să înțelegi ce acoperă pagina și cum se leagă serviciile de tema principală.

Exercițiul trei: un coleg propune un buton „Programare confirmată” care doar schimbă un text în pagină. Explică de ce nu îl introducem. O confirmare presupune o operație realizată și un rezultat real; proiectul static nu oferă această funcție. Păstrăm explicația vizibilă și acțiunea indisponibilă. Această corecție ține de acuratețea experienței utilizatorului, nu doar de sintaxa HTML. Un formular frumos nu trebuie să inducă în eroare asupra a ceea ce face.

Predă index.html și o notă cu rezultatul verificării titlurilor, identificatorilor, etichetelor, linkului de salt și controalelor details. Rulează un validator HTML pentru a identifica erorile de marcaj, dar nu trata absența erorilor drept certificare de accesibilitate. Testarea manuală cu tastatura și citirea structurii răspund altor întrebări. Păstrează observațiile proprii, inclusiv o problemă găsită și corectată, pentru a putea compara documentul înainte și după adăugarea CSS.

Atelier de diagnostic: pagina pare corectă, dar structura nu este

Imaginează că un coleg copiază întregul bloc contact de două ori pentru a crea un al doilea formular. Vizual apar două grupuri ordonate, însă identificatorii nume, email și mesaj se repetă. Prima verificare este inventarul id-urilor, nu o captură. A doua este apăsarea fiecărei etichete. A treia este inspectarea numelui accesibil al fiecărui control. Corectura poate fi eliminarea duplicatului dacă nu este necesar sau atribuirea unor identificatori unici și actualizarea tuturor referințelor. Nu schimba numai id-ul fără for: ai rupe asocierea pe care tocmai încerci să o repari.

Un alt caz este introducerea unui h2 în interiorul unui p, deoarece autorul vrea să păstreze un anumit spațiu. Browserul poate închide paragraful înainte de titlu și poate produce noduri diferite de indentarea sursei. Compară sursa cu panoul Elements. Mută titlul în afara paragrafului și gestionează spațiul prin CSS. Această probă explică de ce HTML-ul tolerant la erori nu este o invitație la structură arbitrară: o pagină care se afișează poate avea totuși relații neașteptate între elemente.

Pentru textul alternativ, consideră două contexte ale aceleiași fotografii. Într-un articol despre uzură, imaginea arată un cablu deteriorat, deci alternativa trebuie să comunice defectul relevant. Într-un banner decorativ lângă un text care spune deja ce serviciu este oferit, aceeași fotografie poate să nu adauge informație necesară. Decizia nu se ia după numele fișierului sau după faptul că imaginea este mare. Se ia după rolul ei în înțelegerea conținutului. Notează acel rol înainte să redactezi alternativa.

Verifică și textul linkurilor în afara contextului vizual imediat. Trei legături numite doar „Află mai mult” sunt greu de diferențiat într-o listă de linkuri. În proiect am folosit destinații descrise prin serviciu, chiar dacă toate duc la aceeași zonă demonstrativă. Nu promitem că destinația va filtra automat formularul. Dacă ai schimba textul în „Rezervă revizia”, ai introduce o așteptare pe care pagina nu o satisface. Semantica și formularea textului trebuie analizate împreună.

Pentru întrebările details, verifică atât starea închisă, cât și pe cea deschisă. Răspunsul trebuie să rămână în fluxul documentului și să nu acopere următorul control. Nu pune toată informația critică despre caracterul fictiv în interiorul unei întrebări închise: cititorul trebuie să afle limita înainte de a completa formularul. În proiect aceeași limită apare vizibil în introducere și lângă formular, iar întrebarea oferă o explicație suplimentară. Repetarea are aici o funcție de context, nu de umplere a paginii.

În nota de verificare separă defectele de sintaxă de cele de sens. Un id duplicat este o problemă structurală detectabilă automat. Un text de link care promite o operație inexistentă poate fi perfect valid sintactic și totuși greșit pentru cititor. Un validator nu poate decide singur dacă formularea serviciului este onestă. Predarea bună include ambele tipuri de observație și corectura aplicată, astfel încât următoarea persoană să înțeleagă de ce documentul a fost schimbat.

Verificarea finală a câmpurilor fără expediere

În inspector, selectează câmpul email și compară starea lui când este gol, când conține text fără format de adresă și când conține ana@example.test. Required și type=email participă la validitatea nativă, dar nu validează o persoană. În acest proiect nu este nevoie să apeși un buton activ de trimitere pentru a observa diferența. Dacă browserul oferă completare automată, folosește numai date fictive și verifică valoarea înainte de a salva capturi pentru exercițiu.

La apăsarea tastei Enter într-un câmp, pagina de referință trebuie să rămână o demonstrație fără expediere. Verifică lipsa unei navigări sau cereri noi, nu doar lipsa unui mesaj de succes. Dacă ai schimbat structura formularului sau ai activat un submit, comportamentul poate fi diferit. Revino la referință înainte de predare și păstrează nota despre limita funcțională vizibilă. Această probă leagă explicația din pagină de comportamentul efectiv, evitând o interfață care spune un lucru și face altul.

Documentație oficială pentru aprofundare

Ți-a plăcut lecția? Continuă cursul complet

Ai citit o lecție gratuită. Celelalte lecții, aplicațiile practice și materialele se deblochează odată cu cursul.

79 lei

Plată unică, acces pe viață la toate cele 8 lecții.

Vezi ce conține cursul →

Folosim cookie-uri esențiale pentru funcționarea site-ului și, cu acordul tău, cookie-uri de analiză și publicitate. Partenerii noștri, inclusiv Google, pot folosi cookie-uri pentru a afișa reclame relevante. Detalii în Politica de cookie-uri.