← Back to course

Mini Progetto Finale: Landing Page Responsive

Mini Progetto Finale: Landing Page Responsive

Benvenuto nell’ultima lezione di questo corso CSS.

Ce l’hai fatta.

Il tuo browser è sopravvissuto.

Il tuo CSS è sopravvissuto.

Probabilmente.

In questa lezione uniremo tutto quello che hai imparato in un mini progetto.

Costruiremo una landing page responsive.

Avrà:

Qui CSS smette di essere una serie di proprietà isolate e diventa un vero sito.

I piccoli pezzi CSS finalmente si incontrano.

Come una cena di famiglia frontend.

Speriamo con meno discussioni.

Cosa Costruirai

Creerai una landing page per un servizio web immaginario chiamato FastSite Studio.

La pagina avrà:

Questo progetto usa molte cose delle lezioni precedenti:

Nessun nuovo mostro oggi.

Solo mettere insieme gli strumenti.

Come montare mobili, ma con meno viti misteriose.

Crea il Progetto

Crea una cartella per il progetto finale:

mkdir css-lesson10
cd css-lesson10
touch index.html
touch style.css

Dovresti avere:

css-lesson10/
  index.html
  style.css

Apri la cartella nel tuo editor.

Questo è il nostro playground CSS finale.

Niente paura.

Solo punti e virgola.

E forse un refresh drammatico.

Scrivi l’HTML

Apri index.html e aggiungi questo:

<!DOCTYPE html>
<html lang="it">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>FastSite Studio</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header class="hero">
    <nav class="navbar">
      <h1 class="logo">FastSite Studio</h1>

      <div class="nav-links">
        <a href="#">Home</a>
        <a href="#">Funzionalità</a>
        <a href="#">Prezzi</a>
        <a href="#">Contatto</a>
      </div>
    </nav>

    <section class="hero-content">
      <p class="eyebrow">Modern CSS Project</p>
      <h2>Costruisci un Sito Veloce, Pulito e Responsive</h2>
      <p>
        Pratica layout CSS, responsive design, card, pulsanti, ombre e transitions in un mini progetto completo.
      </p>

      <div class="hero-actions">
        <a href="#" class="button primary-button">Inizia a Costruire</a>
        <a href="#" class="button secondary-button">Vedi Funzionalità</a>
      </div>
    </section>
  </header>

  <main>
    <section class="section intro-section">
      <div class="section-header">
        <p class="eyebrow dark">Cosa Pratichi</p>
        <h2>Qui Tutto Si Unisce</h2>
        <p>
          Questo progetto combina le competenze CSS più importanti per principianti in un layout riutilizzabile per siti reali.
        </p>
      </div>

      <div class="feature-grid">
        <article class="feature-card">
          <div class="icon">⚡</div>
          <h3>Layout Veloce</h3>
          <p>Usa Grid e Flexbox per creare sezioni pulite, strutturate e facili da modificare.</p>
        </article>

        <article class="feature-card">
          <div class="icon">📱</div>
          <h3>Responsive Design</h3>
          <p>Fai adattare la pagina a laptop, tablet e telefoni senza caos da scroll orizzontale.</p>
        </article>

        <article class="feature-card">
          <div class="icon">🎨</div>
          <h3>Stile Rifinito</h3>
          <p>Aggiungi colori, bordi, ombre, spacing ed effetti hover per far sembrare la pagina completa.</p>
        </article>
      </div>
    </section>

    <section class="section pricing-section">
      <div class="section-header">
        <p class="eyebrow dark">Prezzi</p>
        <h2>Scegli la Tua Avventura CSS</h2>
        <p>
          Queste pricing cards sono solo esercizio, ma il pattern di layout viene usato in landing page reali ovunque.
        </p>
      </div>

      <div class="pricing-grid">
        <article class="pricing-card">
          <h3>Basic</h3>
          <p class="price">€99</p>
          <p>Perfetto per praticare le basi del layout.</p>
          <ul>
            <li>Layout one-page</li>
            <li>Card semplici</li>
            <li>Responsive design base</li>
          </ul>
          <a href="#" class="button card-button">Scegli Basic</a>
        </article>

        <article class="pricing-card featured-card">
          <p class="badge">Popolare</p>
          <h3>Standard</h3>
          <p class="price">€199</p>
          <p>Ideale per costruire una pagina responsive rifinita.</p>
          <ul>
            <li>Sezioni responsive</li>
            <li>Card e pulsanti</li>
            <li>Hover transitions</li>
          </ul>
          <a href="#" class="button card-button">Scegli Standard</a>
        </article>

        <article class="pricing-card">
          <h3>Premium</h3>
          <p class="price">€299</p>
          <p>Per quando il tuo CSS è pronto a mettersi il completo.</p>
          <ul>
            <li>Layout avanzato</li>
            <li>Stile visivo rifinito</li>
            <li>Struttura riutilizzabile</li>
          </ul>
          <a href="#" class="button card-button">Scegli Premium</a>
        </article>
      </div>
    </section>
  </main>

  <footer class="site-footer">
    <p>Creato con HTML, CSS, pazienza e qualche coraggioso punto e virgola.</p>
  </footer>
</body>
</html>

Questo HTML ci dà tutta la struttura.

Ora serve CSS.

Al momento la pagina è solo HTML grezzo.

Utile, ma non affascinante.

Come pasta senza sugo.

Tecnicamente cibo.

Emotivamente incompleta.

Aggiungi Stili Base

Apri style.css e aggiungi:

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: Arial, sans-serif;
  background-color: #f3f4f6;
  color: #111827;
}

a {
  color: inherit;
  text-decoration: none;
}

ul {
  padding-left: 20px;
}

Questo ci dà:

Buona base.

Un progetto finale ha bisogno di una base stabile.

Altrimenti CSS comincia a comportarsi come un carrello della spesa con una ruota rotta.

Stilizza la Hero

Aggiungi:

.hero {
  background: linear-gradient(135deg, #111827, #1e3a8a);
  color: white;
}

Questo crea lo sfondo scuro della hero.

Ora stilizza la navbar:

.navbar {
  max-width: 1100px;
  margin: 0 auto;
  padding: 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.logo {
  margin: 0;
  font-size: 24px;
}

.nav-links {
  display: flex;
  gap: 20px;
  font-weight: 700;
}

La navbar ora usa Flexbox.

Logo a sinistra.

Link a destra.

Pulita.

Semplice.

Abbastanza professionale da far chiedere a CSS un profilo LinkedIn.

Stilizza il Contenuto Hero

Aggiungi:

.hero-content {
  max-width: 850px;
  margin: 0 auto;
  padding: 90px 24px 110px;
  text-align: center;
}

.eyebrow {
  margin: 0 0 16px;
  color: #bfdbfe;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.hero-content h2 {
  margin: 0 0 20px;
  font-size: 58px;
  line-height: 1.1;
}

.hero-content p {
  margin: 0 auto;
  max-width: 700px;
  color: #dbeafe;
  font-size: 20px;
  line-height: 1.7;
}

Ora la hero ha:

Questa è gerarchia visiva.

L’utente vede prima ciò che conta.

Prima il titolo.

Poi il testo.

Poi il pulsante.

Un buon layout non costringe l’utente a cercare il significato con una torcia.

Stilizza i Pulsanti

Aggiungi:

.hero-actions {
  display: flex;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 28px;
}

.button {
  display: inline-block;
  padding: 14px 22px;
  border-radius: 999px;
  font-weight: 700;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.button:hover {
  transform: translateY(-3px);
}

.primary-button {
  background-color: white;
  color: #1e3a8a;
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.22);
}

.secondary-button {
  border: 2px solid rgba(255, 255, 255, 0.5);
  color: white;
}

Ora la hero ha due pulsanti.

Uno primary.

Uno secondary.

Il primary button è più forte.

Il secondary button è più calmo.

È importante.

Non tutti i pulsanti devono urlare.

Se tutti i pulsanti urlano, la pagina diventa una riunione dove parlano tutti insieme.

Terribile.

Crea Stili Riutilizzabili per le Sezioni

Aggiungi:

.section {
  max-width: 1100px;
  margin: 0 auto;
  padding: 72px 24px;
}

.section-header {
  max-width: 760px;
  margin: 0 auto 36px;
  text-align: center;
}

.eyebrow.dark {
  color: #2563eb;
}

.section-header h2 {
  margin: 0 0 16px;
  font-size: 38px;
  line-height: 1.2;
}

.section-header p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.7;
}

Ora le sezioni hanno spacing coerente.

La coerenza conta.

Un sito con spacing casuale sembra nervoso.

Come se CSS stesse cercando di ricordare dove ha parcheggiato la macchina.

Crea le Feature Cards

Aggiungi:

.feature-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.feature-card {
  background-color: white;
  padding: 28px;
  border: 2px solid #e5e7eb;
  border-radius: 24px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.06);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.feature-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.1);
}

.icon {
  width: 52px;
  height: 52px;
  border-radius: 18px;
  background-color: #dbeafe;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  margin-bottom: 18px;
}

.feature-card h3 {
  margin: 0 0 12px;
  font-size: 24px;
}

.feature-card p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.7;
}

Questo usa CSS Grid per le cards.

Tre colonne su desktop.

Buono spacing.

Ombre morbide.

Movimento hover.

La pagina comincia a sembrare che sappia cosa sta facendo.

Pericolosamente professionale.

Stilizza la Sezione Pricing

Aggiungi:

.pricing-section {
  padding-top: 40px;
}

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.pricing-card {
  position: relative;
  background-color: white;
  padding: 32px;
  border: 2px solid #e5e7eb;
  border-radius: 28px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.06);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.pricing-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.1);
  border-color: #2563eb;
}

.pricing-card h3 {
  margin: 0 0 12px;
  font-size: 26px;
}

.price {
  margin: 0 0 16px;
  font-size: 42px;
  font-weight: 800;
  color: #1e3a8a;
}

.pricing-card p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.6;
}

.pricing-card li {
  margin-bottom: 8px;
  color: #374151;
}

Ora le pricing cards sono strutturate.

Il prezzo è grande.

Il testo è leggibile.

Le card hanno profondità.

Una pricing card deve essere facile da leggere velocemente.

Gli utenti non dovrebbero aver bisogno di una mappa del tesoro per trovare il prezzo.

Pricing Card Featured

Aggiungi:

.featured-card {
  border-color: #2563eb;
  background-color: #eff6ff;
}

.badge {
  display: inline-block;
  margin: 0 0 16px;
  background-color: #2563eb;
  color: white !important;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 14px !important;
  font-weight: 700;
}

La card centrale ora si distingue.

Ha un badge.

Ha un bordo blu.

Ha uno sfondo azzurro chiaro.

Dice:

“Guarda qui.”

Non:

“GUARDA QUI O INIZIO A LAMPEGGIARE.”

Bene.

Pulsanti delle Card

Aggiungi:

.card-button {
  margin-top: 18px;
  background-color: #2563eb;
  color: white;
  text-align: center;
  width: 100%;
}

.card-button:hover {
  box-shadow: 0 12px 25px rgba(37, 99, 235, 0.3);
}

Ora ogni pricing card ha un pulsante full-width.

È comune nelle sezioni pricing.

Facile da cliccare.

Facile da capire.

Nessun mistero.

Il mistero va bene nei romanzi detective.

Non nelle pricing cards.

Footer

Aggiungi:

.site-footer {
  text-align: center;
  padding: 36px 24px;
  color: #6b7280;
}

Footer semplice.

Senza drammi.

I progetti finali non hanno bisogno di footer drammatici.

Il footer non è il protagonista.

Rendilo Responsive

Ora aggiungi media queries.

Prima per i tablet:

@media (max-width: 850px) {
  .hero-content h2 {
    font-size: 44px;
  }

  .feature-grid,
  .pricing-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

Ora le card diventano due colonne su schermi medi.

Poi per i telefoni:

@media (max-width: 600px) {
  .navbar {
    flex-direction: column;
    align-items: flex-start;
  }

  .nav-links {
    flex-direction: column;
    gap: 12px;
  }

  .hero-content {
    text-align: left;
    padding: 64px 20px 80px;
  }

  .hero-content h2 {
    font-size: 36px;
  }

  .hero-content p {
    font-size: 18px;
  }

  .hero-actions {
    justify-content: flex-start;
  }

  .section {
    padding: 56px 20px;
  }

  .section-header {
    text-align: left;
  }

  .section-header h2 {
    font-size: 30px;
  }

  .feature-grid,
  .pricing-grid {
    grid-template-columns: 1fr;
  }
}

Ora la pagina funziona sui telefoni.

La navbar si impila.

Le card diventano una colonna.

Il testo diventa più piccolo.

Lo spacing diventa più compatto.

Questo è responsive design che fa il suo lavoro.

Niente scroll laterale.

Niente card minuscole illeggibili.

Niente rabbia dell’utente.

Ottimo.

Aggiungi Supporto per Reduced Motion

Aggiungi questo alla fine:

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none;
  }
}

Questo aiuta gli utenti che preferiscono meno movimento.

È un piccolo dettaglio.

Ma i buoni siti si preoccupano dei dettagli.

E degli utenti.

Soprattutto degli utenti.

CSS esiste per le persone, non solo per gli screenshot.

CSS Completo

Il tuo style.css dovrebbe essere così:

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: Arial, sans-serif;
  background-color: #f3f4f6;
  color: #111827;
}

a {
  color: inherit;
  text-decoration: none;
}

ul {
  padding-left: 20px;
}

.hero {
  background: linear-gradient(135deg, #111827, #1e3a8a);
  color: white;
}

.navbar {
  max-width: 1100px;
  margin: 0 auto;
  padding: 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.logo {
  margin: 0;
  font-size: 24px;
}

.nav-links {
  display: flex;
  gap: 20px;
  font-weight: 700;
}

.hero-content {
  max-width: 850px;
  margin: 0 auto;
  padding: 90px 24px 110px;
  text-align: center;
}

.eyebrow {
  margin: 0 0 16px;
  color: #bfdbfe;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.hero-content h2 {
  margin: 0 0 20px;
  font-size: 58px;
  line-height: 1.1;
}

.hero-content p {
  margin: 0 auto;
  max-width: 700px;
  color: #dbeafe;
  font-size: 20px;
  line-height: 1.7;
}

.hero-actions {
  display: flex;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 28px;
}

.button {
  display: inline-block;
  padding: 14px 22px;
  border-radius: 999px;
  font-weight: 700;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.button:hover {
  transform: translateY(-3px);
}

.primary-button {
  background-color: white;
  color: #1e3a8a;
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.22);
}

.secondary-button {
  border: 2px solid rgba(255, 255, 255, 0.5);
  color: white;
}

.section {
  max-width: 1100px;
  margin: 0 auto;
  padding: 72px 24px;
}

.section-header {
  max-width: 760px;
  margin: 0 auto 36px;
  text-align: center;
}

.eyebrow.dark {
  color: #2563eb;
}

.section-header h2 {
  margin: 0 0 16px;
  font-size: 38px;
  line-height: 1.2;
}

.section-header p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.7;
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.feature-card {
  background-color: white;
  padding: 28px;
  border: 2px solid #e5e7eb;
  border-radius: 24px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.06);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.feature-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.1);
}

.icon {
  width: 52px;
  height: 52px;
  border-radius: 18px;
  background-color: #dbeafe;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  margin-bottom: 18px;
}

.feature-card h3 {
  margin: 0 0 12px;
  font-size: 24px;
}

.feature-card p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.7;
}

.pricing-section {
  padding-top: 40px;
}

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.pricing-card {
  position: relative;
  background-color: white;
  padding: 32px;
  border: 2px solid #e5e7eb;
  border-radius: 28px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.06);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.pricing-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.1);
  border-color: #2563eb;
}

.pricing-card h3 {
  margin: 0 0 12px;
  font-size: 26px;
}

.price {
  margin: 0 0 16px;
  font-size: 42px;
  font-weight: 800;
  color: #1e3a8a;
}

.pricing-card p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.6;
}

.pricing-card li {
  margin-bottom: 8px;
  color: #374151;
}

.featured-card {
  border-color: #2563eb;
  background-color: #eff6ff;
}

.badge {
  display: inline-block;
  margin: 0 0 16px;
  background-color: #2563eb;
  color: white !important;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 14px !important;
  font-weight: 700;
}

.card-button {
  margin-top: 18px;
  background-color: #2563eb;
  color: white;
  text-align: center;
  width: 100%;
}

.card-button:hover {
  box-shadow: 0 12px 25px rgba(37, 99, 235, 0.3);
}

.site-footer {
  text-align: center;
  padding: 36px 24px;
  color: #6b7280;
}

@media (max-width: 850px) {
  .hero-content h2 {
    font-size: 44px;
  }

  .feature-grid,
  .pricing-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 600px) {
  .navbar {
    flex-direction: column;
    align-items: flex-start;
  }

  .nav-links {
    flex-direction: column;
    gap: 12px;
  }

  .hero-content {
    text-align: left;
    padding: 64px 20px 80px;
  }

  .hero-content h2 {
    font-size: 36px;
  }

  .hero-content p {
    font-size: 18px;
  }

  .hero-actions {
    justify-content: flex-start;
  }

  .section {
    padding: 56px 20px;
  }

  .section-header {
    text-align: left;
  }

  .section-header h2 {
    font-size: 30px;
  }

  .feature-grid,
  .pricing-grid {
    grid-template-columns: 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none;
  }
}

Salva il file.

Aggiorna il browser.

Ridimensiona la finestra.

Passa con il mouse su card e pulsanti.

Ora hai una landing page responsive completa.

Complimenti.

Questo non è più solo esercizio CSS.

È una struttura web riutilizzabile.

Puoi usare questo pattern per:

Ora il tuo CSS ha un lavoro.

Finalmente.

Cosa Hai Praticato

In questo progetto finale hai praticato:

È tanto.

Non fingere che sia niente.

CSS sembra semplice finché non inizia a discutere con la dimensione dello schermo.

Tu hai gestito la cosa.

Bene.

Errori Comuni

Cercare di Rendere Tutto Perfetto Subito

Non cercare di rendere la pagina perfetta al primo tentativo.

Costruisci a fasi:

  1. Struttura HTML.
  2. CSS base.
  3. Layout.
  4. Card.
  5. Responsive design.
  6. Rifinitura.

Se provi a fare tutto insieme, CSS sente la paura.

Dimenticare il Mobile

Ridimensiona sempre il browser.

Testa sempre schermi piccoli.

Una pagina che funziona solo su desktop non è finita.

Sta solo fingendo.

Aggiungere Troppa Decorazione

Una pagina pulita è meglio di una pagina rumorosa.

Usa:

Non servono 19 gradienti e un pulsante che balla come se sentisse musica.

Mini Sfida

Personalizza questo progetto.

Cambia:

Poi trasformalo nella tua landing page.

Può diventare:

È così che iniziano i veri progetti web.

Struttura semplice.

Poi personalizzazione.

Poi miglioramento.

Poi caffè.

Riassunto

Hai finito il corso CSS.

Hai imparato:

CSS non è solo decorazione.

CSS è layout.

Struttura.

Leggibilità.

Responsiveness.

User experience.

E a volte danno emotivo.

Ma ora sei più forte.

Parole Finali

Continua a praticare.

Prendi questo progetto e ricostruiscilo a memoria.

Poi cambialo.

Rompilo.

Sistemalo.

Fanne un altro.

È così che CSS diventa naturale.

Non leggendo mille proprietà.

Ma costruendo cose finché le dita sanno dove vive display: grid.

Complimenti.

La tua toolbox CSS è pronta.

Ora vai a costruire qualcosa di veloce, pulito, responsive e leggermente meno caotico di quanto internet meriti.