Invatare Atomica

Proiect pagina web interactiva

Progres lectie:
0%
🎯

Obiectivul lectiei

Vei integra HTML, CSS si JavaScript intr-un proiect web complet: o pagina personala cu navigatie, sectiuni de continut, design responsive, formular de contact validat si mod intunecat. Modul optional/extensie: Programa TIC cls. XII (mat-info) acopera societate digitala, continuturi digitale si retele de calculatoare — HTML/CSS/JS nu sunt in programa cls. XII; apar la cls. X. Lectia este inclusa ca aprofundare optionala pentru elevii interesati de web development.

Dupa aceasta lectie vei putea:

  • Sa organizezi un proiect web cu structura corecta de fisiere si foldere
  • Sa construiesti o pagina cu sectiuni header, main, footer semantice
  • Sa aplici Flexbox si media queries pentru un layout responsive (desktop/tablet/mobil)
  • Sa adaugi interactivitate cu JavaScript: mod intunecat, formular validat, contor de caractere
  • Sa adaugi meta tags SEO corecte (description, viewport, Open Graph)
  • Sa descrii etapele unui proiect web: planificare, design, implementare, testare, publicare

Incearca singur!

Provocare:

Inainte sa citesti lectia, gandeste-te: care sunt cele 3 tehnologii folosite pentru a construi o pagina web interactiva si ce face fiecare?

💡 Ai nevoie de un indiciu?

HTML = structura (scheletul paginii: titluri, paragrafe, linkuri, imagini).

CSS = stilizarea (culorile, fonturile, layout-ul, animatiile).

JavaScript = comportamentul (ce se intampla cand dai click, validare formular, animatii dinamice).

1

1. Structura proiectului si HTML semantic

Un proiect web inseamna mai mult decat un singur fisier. El are o structura de foldere clara si foloseste HTML semantic: tag-uri care descriu sensul continutului, nu doar aspectul.
Structura unui proiect web (afisata cu Python):
# Structura proiect rulata cu Python
structura = {
    "pagina-mea/": {
        "index.html": "Pagina principala",
        "despre.html": "Pagina Despre mine",
        "contact.html": "Pagina Contact",
        "assets/css/style.css": "Stiluri",
        "assets/js/main.js": "Script JS",
        "assets/img/profil.jpg": "Foto"
    }
}
for fisier, rol in structura["pagina-mea/"].items():
    print(f"  {fisier} → {rol}")
Output real (rulat cu python):
  index.html → Pagina principala
  despre.html → Pagina Despre mine
  contact.html → Pagina Contact
  assets/css/style.css → Stiluri
  assets/js/main.js → Script JS
  assets/img/profil.jpg → Foto
Structura HTML semantica a paginii principale:
<!-- Structura semantica HTML -->
<!DOCTYPE html>
<html lang="ro">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Pagina Mea</title>
  <link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
  <header>            <!-- antetul paginii -->
    <nav>...</nav>    <!-- meniu navigatie -->
  </header>
  <main>              <!-- continut principal -->
    <section id="hero">...</section>
    <section id="despre">...</section>
    <section id="contact">...</section>
  </main>
  <footer>...</footer>  <!-- subsolul paginii -->
  <script src="assets/js/main.js"></script>
</body>
</html>
De ce semantic?

Tag-urile semantice (<header>, <main>, <footer>, <section>, <nav>) ajuta motoarele de cautare sa inteleaga pagina si imbunatatesc accesibilitatea pentru utilizatorii cu dizabilitati (cititoare de ecran).

2

2. CSS: Flexbox pentru layout si navigatie

Flexbox este sistemul CSS pentru a aranja elementele intr-un rand sau coloana, cu control precis asupra spatierilor si alinierii. Este baza oricarui layout modern.
Verificare proprietati Flexbox (Python):
# Proprietatile Flexbox verificate cu Python
flexbox_props = [
    "display: flex",
    "justify-content",
    "align-items",
    "flex-direction"
]
for prop in flexbox_props:
    print(f"  PREZENT: {prop}")
Output real (rulat cu python):
  PREZENT: display: flex
  PREZENT: justify-content
  PREZENT: align-items
  PREZENT: flex-direction
/* Navigatie cu Flexbox */
nav {
    display: flex;
    justify-content: space-between;  /* spatiere uniforma */
    align-items: center;             /* aliniere verticala */
    background-color: #1a1a2e;
    padding: 1rem 2rem;
}
nav a {
    color: white;
    text-decoration: none;
    font-size: 1rem;
    padding: 0.5rem 1rem;
    border-radius: 6px;
    transition: background 0.3s;
}
nav a:hover {
    background-color: rgba(255,255,255,0.15);
}

/* Sectiunea hero - centrata cu Flexbox */
.hero {
    display: flex;
    flex-direction: column;          /* pe coloana */
    justify-content: center;
    align-items: center;
    min-height: 60vh;
    background: linear-gradient(135deg, #1a1a2e, #16213e);
    color: white;
    text-align: center;
}

/* Cards - aranjate in rand */
.cards-grid {
    display: flex;
    gap: 1.5rem;
    justify-content: center;
    flex-wrap: wrap;         /* trec pe rand nou daca nu incap */
}
Valori cheie justify-content:
  • flex-start — aliniere la stanga
  • flex-end — aliniere la dreapta
  • center — centrat
  • space-between — spatiere uniforma, cu margini la capete
  • space-around — spatiere uniforma inclusiv la margini
3

3. Design responsive cu media queries

Design responsive inseamna ca pagina web arata bine pe orice dispozitiv: desktop, tableta, telefon. Se realizeaza cu media queries — reguli CSS care se aplica doar la anumite dimensiuni de ecran.
Breakpoints verificate cu Python:
# Breakpoints standard (verificare Python)
breakpoints = [(768, "Tableta"), (480, "Mobil")]
for bp, nivel in breakpoints:
    print(f"  @media (max-width: {bp}px) → {nivel}")
Output real (rulat cu python):
  @media (max-width: 768px) → Tableta
  @media (max-width: 480px) → Mobil
/* Desktop - stil default (fara media query) */
.cards-grid {
    display: flex;
    gap: 1.5rem;
    justify-content: center;
}
.card {
    width: 280px;
    background: white;
    border-radius: 12px;
    padding: 1.5rem;
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

/* Tableta: max-width 768px */
@media (max-width: 768px) {
    .cards-grid {
        flex-direction: column;    /* carduri pe coloana */
        align-items: center;
    }
    .card {
        width: 90%;
        max-width: 400px;
    }
    nav {
        flex-direction: column;
        gap: 0.5rem;
    }
}

/* Mobil: max-width 480px */
@media (max-width: 480px) {
    .hero h1 {
        font-size: 2rem;    /* titlu mai mic */
    }
    .hero p {
        font-size: 1rem;
        padding: 0 1rem;
    }
}
Regula mobile-first:

La proiecte profesionale se scrie mai intai CSS-ul pentru mobil (ecran mic) si se adauga min-width pentru ecrane mai mari. La scoala, abordarea max-width (desktop-first) este mai usor de inteles si acceptata.

4

4. JavaScript: interactivitate (mod intunecat + formular)

JavaScript adauga comportament paginii: reactii la click-uri, validari de formulare, animatii dinamice. Prin DOM manipulation accesam si modificam elementele HTML din cod JS.
Logica mod intunecat (simulata in Python):
# Simulam toggle dark mode in Python
def toggle_dark_mode(classes):
    if 'dark' in classes:
        classes.remove('dark')
        return classes, 'Modul Intunecat: OFF'
    else:
        classes.append('dark')
        return classes, 'Modul Intunecat: ON'

classes = []
classes, msg = toggle_dark_mode(classes)
print(msg)   # Modul Intunecat: ON
classes, msg = toggle_dark_mode(classes)
print(msg)   # Modul Intunecat: OFF
Output real (rulat cu python):
Modul Intunecat: ON
Modul Intunecat: OFF
// Mod intunecat cu JavaScript
const btnDark = document.getElementById('btn-dark');
const body   = document.body;

btnDark.addEventListener('click', function() {
    body.classList.toggle('dark');  // adauga/elimina clasa
    if (body.classList.contains('dark')) {
        btnDark.textContent = 'Mod Luminos ☀️';
    } else {
        btnDark.textContent = 'Mod Intunecat 🌙';
    }
});

// Contor caractere pentru textarea
const msgArea  = document.getElementById('mesaj');
const counter  = document.getElementById('contor');
const MAX_CHARS = 200;

msgArea.addEventListener('input', function() {
    const left = MAX_CHARS - msgArea.value.length;
    counter.textContent = left + ' caractere ramase';
    counter.style.color = left < 20 ? 'red' : 'gray';
});
Contor simulat Python:
# Contor caractere Python
def count_chars(text, max_chars=200):
    left = max_chars - len(text)
    return len(text), left

used, left = count_chars("Salut, vreau o oferta!", 200)
print(f"{used} folositi, {left} ramasi din 200")
Output real (rulat cu python):
22 folositi, 178 ramasi din 200
5

5. Validare formular cu JavaScript

Validarea formularului verifica datele introduse de utilizator inainte de trimitere. Prin validare pe client (JavaScript) oferim feedback rapid; validarea pe server este obligatorie suplimentar in aplicatii reale.
Logica validare simulata in Python:
# Validare formular - logica Python
def validate_form(name, email, message):
    errors = []
    if not name.strip():
        errors.append("Numele este obligatoriu")
    if not email.strip() or '@' not in email:
        errors.append("Email invalid")
    if len(message.strip()) < 10:
        errors.append("Mesajul trebuie sa aiba cel putin 10 caractere")
    return errors

errs = validate_form("", "nu-e-email", "scurt")
print("Date invalide:", errs)

errs = validate_form("Ion Pop", "ion@email.ro",
                      "Vreau o oferta pentru site.")
print("Date valide:", "OK" if not errs else errs)
Output real (rulat cu python):
Date invalide: ['Numele este obligatoriu', 'Email invalid', 'Mesajul trebuie sa aiba cel putin 10 caractere']
Date valide: OK
// Validare formular cu JavaScript
function validateForm() {
    const name    = document.getElementById('name').value;
    const email   = document.getElementById('email').value;
    const message = document.getElementById('mesaj').value;
    const errors  = [];

    if (!name.trim()) {
        errors.push('Numele este obligatoriu');
    }
    if (!email.includes('@')) {
        errors.push('Email invalid');
    }
    if (message.trim().length < 10) {
        errors.push('Mesajul trebuie sa aiba minim 10 caractere');
    }

    if (errors.length > 0) {
        document.getElementById('form-errors').innerHTML =
            errors.map(e => `<li>${e}</li>`).join('');
        return false;  // opreste trimiterea
    }
    return true;   // trimitere permisa
}

// Atasam la formularul din HTML
document.getElementById('form-contact')
    .addEventListener('submit', function(e) {
        if (!validateForm()) {
            e.preventDefault();  // blocheaza submit
        }
    });
6

6. SEO si meta tags pentru vizibilitate

SEO (Search Engine Optimization) cuprinde tehnicile prin care o pagina web apare mai sus in rezultatele motoarelor de cautare. Meta tags sunt primele si cele mai usoare optimizari SEO.
Verificare meta tags cu Python:
# Verificam prezenta meta tags SEO
import re
meta_tags_html = """
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Pagina personala Ion Pop.">
<title>Ion Pop | Pagina Personala</title>
<meta property="og:title" content="Ion Pop | Pagina Personala">
"""
required = {
    'charset': r'meta\s+charset=',
    'viewport': r'name="viewport"',
    'description': r'name="description"',
    'title': r'<title>',
    'og:title': r'property="og:title"'
}
for name, pattern in required.items():
    ok = bool(re.search(pattern, meta_tags_html))
    print(f"  {'OK' if ok else 'LIPSA'}: {name}")
Output real (rulat cu python):
  OK: charset
  OK: viewport
  OK: description
  OK: title
  OK: og:title
<!-- Meta tags complete pentru SEO -->
<head>
  <meta charset="UTF-8">
  <!-- Esential: afiseaza corect pe mobil -->
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0">
  <!-- Textul din rezultatele Google (max 160 caractere) -->
  <meta name="description"
        content="Pagina personala a lui Ion Pop, pasionat de
        programare si design web. Proiecte, blog si contact.">
  <meta name="author" content="Ion Pop">
  <title>Ion Pop | Pagina Personala</title>

  <!-- Open Graph: afisare in social media -->
  <meta property="og:title"
        content="Ion Pop | Pagina Personala">
  <meta property="og:description"
        content="Pasionat de programare si design web.">
  <meta property="og:type" content="website">

  <link rel="stylesheet" href="assets/css/style.css">
</head>
Reguli SEO de baza:
  • <title>: 50–60 caractere, contine cuvantul cheie principal
  • description: 120–160 caractere, rezuma continutul
  • O singura eticheta <h1> per pagina
  • Toate imaginile au atribut alt descriptiv
  • URL-uri curate: pagina-mea.html nu p123.html

Exercitii practice

Exercitiul 1 (Nivel minim) - Structura HTML

Creeaza fisierul index.html al unui proiect web personal. Pagina trebuie sa contina: <header> cu <nav> si 3 linkuri, <main> cu doua <section> (hero si despre mine), <footer> cu copyright. Adauga meta tag description si viewport corecte.

Exercitiul 2 (Nivel standard) - Layout Flexbox responsive

Stilizeaza pagina din Ex. 1 cu un fisier CSS separat. Navigatia sa foloseasca display: flex; justify-content: space-between;. Sectiunea hero sa fie centrata cu Flexbox (flex-direction: column; align-items: center; min-height: 60vh). Adauga o media query pentru tableta (max-width: 768px) care pune navigatia pe coloana.

Exercitiul 3 (Nivel performanta) - Interactivitate completa

Adauga la proiectul din Ex. 2 urmatoarele functii JavaScript intr-un fisier main.js separat: (1) un buton de toggle dark mode care adauga/elimina clasa dark pe body si schimba textul butonului; (2) un formular de contact cu validare pentru campurile: nume (obligatoriu), email (trebuie sa contina @), mesaj (minim 10 caractere); erori afisate in lista; (3) contor de caractere ramase (max 200) pentru campul mesaj.

Ce ai invatat astazi

  • Structura unui proiect web: foldere, HTML/CSS/JS separate, fisiere media
  • HTML semantic: header, main, footer, section, nav cu sens si scop clar
  • Flexbox: display flex, justify-content, align-items, flex-direction, gap
  • Design responsive: media queries cu breakpoints tablet (768px) si mobil (480px)
  • JavaScript DOM: classList.toggle, addEventListener, getElementById
  • Validare formular: array de erori, conditii de verificare, preventDefault
  • SEO: meta description (max 160 car.), viewport, title, Open Graph

Modulul complet!

Ai parcurs toate lectiile modulului M3 Web si Multimedia. Reveniti la modul pentru recapitulare sau exploreaza urmatorul modul.

Inapoi la modul ↑