Corso di CSS / Creare un sito responsive completo con HTML e CSS

Puoi combinare HTML semantico, variabili CSS condivise, navigazione Flexbox e layout a schede Grid per costruire un piccolo sito web responsivo. Inizia con contenuti leggibili e un layout utilizzabile su schermi stretti, poi aggiungi aggiustamenti per schermi più larghi e stati di interazione visibili.

Definisci la pagina e i controlli di accettazione

Decidi quali contenuti e comportamenti la pagina deve avere prima di applicare lo stile. Su schermi stretti, la navigazione si adatta quando necessario e le schede formano una colonna. Più spazio disponibile consente due o tre colonne. Limita la larghezza complessiva della lettura in modo che il testo non diventi eccessivamente lungo su schermi ampi.

Requisiti Criteri di completamento
Struttura dei contenuti Un titolo principale, una frase introduttiva, tre schede e un piè di pagina vengono letti in ordine.
Schermo stretto Menu e schede leggibili senza scorrimento orizzontale completo
Schermo ampio Le schede sono disposte in più colonne mantenendo la massima larghezza del corpo
navigazione tramite tastiera Un indicatore di focus rende visibili il collegamento per saltare al contenuto, i link del menu e gli altri link di navigazione.
Cambiamenti di contenuto Anche se inserisci descrizioni lunghe e stringhe senza spazi, non vengono troncate da un’altezza fissa.
movimento ridotto Mantiene la navigazione richiesta senza scorrimento fluido e transizioni decorative.

Questo esempio è una schermata statica e non ci sono link sulla scheda stessa. Il menu di introduzione/corso e i grandi link di navigazione si spostano nelle sezioni dello stesso documento. Per ampliare la tua lista di corsi effettivi, inserisci l'URL post verificato nel titolo della scheda. Non è necessario aggiungere forzatamente moduli non utilizzati o animazioni infinite per completare questo esercizio.

Prepara file e HTML semantico

Crea index.html e style.css nella stessa posizione in una cartella vuota. Durante la creazione del file, assicurati che non sia index.html.txt a causa dell'estensione nascosta e salvalo come UTF-8. Il tag link in index.html punta a style.css nella stessa cartella. Non è necessaria alcuna installazione o compilazione separata.

learning-site/
  index.html
  style.css

Per prima cosa, salva l'intero HTML sottostante come index.html. Anche se il CSS è vuoto, il titolo, il link e il contenuto della scheda devono essere letti in ordine. header contiene l’intestazione visibile del sito, nav è la navigazione, main è il contenuto principale e footer è il piè di pagina. Posiziona l'argomento di studio h2 e la scheda h3 sotto h1 nel documento. Questo HTML è un esempio di file indipendente, quindi è separato dalla struttura dei titoli nel corpo di un articolo WordPress.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>A Small Learning Site</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <a class="skip-link" href="#main">Skip to main content</a>
  <header class="site-header">
    <div class="container header-inner">
      <p class="site-name">Learning Notes</p>
      <nav aria-label="Main navigation">
        <a href="#intro">About</a><a href="#lessons">Lessons</a>
      </nav>
    </div>
  </header>
  <main id="main" tabindex="-1">
    <section id="intro" class="hero" aria-labelledby="intro-title">
      <div class="container">
        <h1 id="intro-title">Learn to Build Webpages Step by Step</h1>
        <p>Structure content with HTML and adapt its appearance with CSS.</p>
        <a class="button" href="#lessons">Explore the lessons</a>
      </div>
    </section>
    <section id="lessons" class="lessons container" aria-labelledby="lessons-title">
      <h2 id="lessons-title">Learning topics</h2>
      <ul class="card-grid" role="list">
        <li><article class="card"><h3>HTML structure</h3><p>Organize content with headings and paragraphs.</p></article></li>
        <li><article class="card"><h3>CSS styles</h3><p>Adjust colors, fonts, and spacing.</p></article></li>
        <li><article class="card"><h3>Responsive layout</h3><p>Arrange cards to fit the available width.</p></article></li>
      </ul>
    </section>
  </main>
  <footer class="site-footer"><div class="container"><p>Small learning site exercise</p></div></footer>
</body>
</html>

Il collegamento rapido al testo principale è connesso all'ID di main. tabindex="-1" permette a main di ricevere il focus senza aggiungerlo all'ordine normale di tabulazione. Attiva un link del menu o il collegamento per saltare al contenuto per navigare a quella sezione e assicurati che la navigazione con tastiera continui dal contenuto principale. Per lo scopo e la composizione del collegamento rapido, consulta la tecnica W3C per saltare al contenuto principale.

Imposta valori condivisi e larghezza del contenuto

Inizia style.css con la sezione seguente. Nominare le variabili dei colori in base al loro ruolo rende più semplice cambiare il colore di accento condiviso. border-box include padding e bordi nella larghezza dichiarata, semplificando le dimensioni. Stabilisci un layout di base che possa accogliere contenuti in crescita invece di assegnare dimensioni fisse ovunque. Prima di modificare i valori condivisi, ripassa ambito ed ereditarietà in Variabili CSS: var(), ambito, ereditarietà e valori di ripiego.

/* Shared values and base styles */
:root {
  --ink: #183044;
  --accent: #166b92;
  --surface: #eef6fa;
  --line: #c9dbe4;
  --focus: #164f73;
}
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; color: var(--ink); font-family: sans-serif; line-height: 1.6; }
a { color: var(--accent); text-underline-offset: .15em; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.container { width: min(100% - 2rem, 68rem); margin-inline: auto; }
.container, .card { overflow-wrap: anywhere; }

La larghezza del contenitore è la minore tra “la larghezza disponibile meno 2rem complessivi” e 68rem. Su schermi stretti lascia 1rem per lato; su quelli ampi limita la larghezza a 68rem. auto per margin-inline centra l’area. overflow-wrap: anywhere consente agli indirizzi o agli identificatori lunghi senza spazi di andare a capo, se necessario. Deve essere fatta una distinzione tra la pratica che aumenta solo la lunghezza di una frase generale e la pratica che aggiunge una parola lunga.

Se aggiorni a questo punto, verranno applicati i colori, il font predefinito e la larghezza del contenuto, ma intestazioni e schede non saranno ancora disposte nei dettagli. Se non ci sono cambiamenti, controlla il percorso del file prima di aggiungere la sezione successiva. I concetti di dimensione fluida e larghezza massima sono collegati ai layout CSS fluidi con min, max e clamp.

Costruisci la navigazione Flexbox e i percorsi del focus

Aggiungi la seguente sezione sotto Regole Comuni in style.css: La posizione tra il nome del sito e il menu è gestita da header-inner, e lo spazio all'interno del menu è gestito da nav. Gestendo separatamente queste due spaziature, puoi ridurre la possibilità di cambiamenti involontari nello spazio tra i link del menu quando modifichi lo spazio complessivo dell'header. I principi di base della direzione degli assi e del posizionamento degli elementi si possono trovare in Fondamenti di Flexbox: contenitori, elementi e assi.

/* Navigation and header */
.skip-link { position: absolute; left: 1rem; top: -6rem; padding: .5rem; background: white; }
.skip-link:focus { top: 1rem; z-index: 10; }
.site-header { border-bottom: 1px solid var(--line); }
.header-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: .5rem 1.5rem; padding-block: 1rem; }
.site-name { margin: 0; font-weight: 700; }
nav { display: flex; flex-wrap: wrap; gap: 1rem; }

flex-wrap posiziona l'elemento sulla riga successiva se non c'è abbastanza spazio. Avere un menu su due righe su uno schermo stretto non è un fallimento. I criteri per giudicare sono se ci sono link sovrapposti, tagliati o non cliccabili. Per mantenere un ordine di navigazione significativo, evita di invertire soltanto l’ordine visivo degli elementi con il CSS.

Il collegamento per saltare al contenuto viene normalmente posizionato al di fuori della parte superiore dello schermo e reso visibile quando riceve il focus. Nasconderlo con display:none non raggiunge lo stesso scopo perché non riceve nemmeno il focus tramite tastiera. Alla prima pressione di Tab deve apparire Skip to main content. Premi Invio e verifica che la successiva pressione di Tab raggiunga il link principale dell’introduzione. Il contorno di focus scuro è stato scelto per risaltare sia sullo sfondo bianco che su quello introduttivo.

Stilizzare l'introduzione fluida e gli stati dei collegamenti

Aggiungere le sezioni seguenti completa lo sfondo introduttivo, il titolo e i grandi collegamenti di navigazione. Il clamp della dimensione del titolo vincola i valori minimo, fluido e massimo. Il carattere non diventa infinitamente più grande all'aumentare della larghezza, e anche l'impostazione della dimensione del carattere, compreso il termine rem, viene presa in considerazione. È necessaria una verifica separata dello schermo per vedere se sia effettivamente facile da leggere quando l'utente ingrandisce.

/* Introduction and navigation link */
.hero { padding-block: clamp(3rem, 8vw, 6rem); background: var(--surface); }
.hero h1 { max-width: 18ch; margin-block: 0 1rem;
  font-size: clamp(1.8rem, 1.2rem + 2vw, 3rem); line-height: 1.25; }
.hero p { max-width: 50ch; }
.button { display: inline-block; margin-top: .5rem; padding: .7rem 1rem;
  border-radius: .4rem; background: var(--accent); color: white; text-decoration: none;
  transition: background-color 180ms ease; }
.button:hover { background: #104d6a; }

L'intestazione max-width: 18ch utilizza la larghezza del glifo “0” del carattere; non garantisce 18 lettere per riga. La sua line-height controlla le righe di intestazione a capo, mentre il paragrafo introduttivo è limitato a 50ch. Questo esempio utilizza caratteri sans-serif di sistema e non scarica alcun carattere esterno.

Il collegamento principale usa un elemento a perché porta alla sezione delle lezioni nello stesso documento. Per un’azione che cambia uno stato senza navigare, valuta invece un elemento button. Vengono utilizzate solo transizioni del colore di sfondo al passaggio del mouse, e non sono richiesti movimenti decorativi o ingrandimenti. Lo stato di messa a fuoco può essere confermato da un contorno comune.

Crea schede a griglia che possono accogliere contenuti

Aggiungi le seguenti sezioni per completare la tua scheda corso e il piè di pagina. Rimuovi i margini e i puntini predefiniti della lista, ma lascia le strutture ul e li nell'HTML. Se una lista con list-style: none è al di fuori di nav, potrebbe non essere riconosciuta come lista nell'albero di accessibilità di Safari. Nell'esempio, ul specifica role="list" per specificare il ruolo della lista. Questa condizione è descritta nella spiegazione MDN dell’accessibilità delle liste. L'ordine di lettura dell'HTML non cambia per la disposizione di righe e colonne nella Griglia.

/* Cards and footer */
.lessons { padding-block: 3rem; }
.lessons h2 { margin-block: 0 1.5rem; }
.card-grid { display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1rem; margin: 0; padding: 0; list-style: none; }
.card-grid > li { min-width: 0; }
.card { height: 100%; padding: 1.5rem; border: 1px solid var(--line); border-radius: .5rem; }
.card h3 { margin-block: 0 .75rem; }
.card p { margin-block: 0; }
.site-footer { padding-block: 2rem; border-top: 1px solid var(--line); }
.site-footer p { margin: 0; }

CSS Grid: repeat, auto-fit, auto-fill e aree spiega come creare colonne in cui è possibile inserire contenuti, e minmax() determina la dimensione minima e la dimensione espandibile di ciascuna colonna. Il valore minimo di min(100%, 16rem) fa sì che la scheda si riduca a quella larghezza quando il suo elemento padre è più stretto di 16rem. Lo spazio libero viene distribuito alle colonne con 1fr. auto-fit comprime le tracce vuote: con tre schede effettive, una maggiore larghezza non crea una quarta scheda. Vedi MDN: repeat() e MDN: minmax().

A condizione che la dimensione del testo a livello superiore sia di 16px e la larghezza disponibile della pagina sia la stessa del viewport, la larghezza minima della scheda è di 256px, il gap è di 16px e i margini totali sinistro e destro sono di 32px. È necessario almeno 560px di spazio per due colonne e 832px per tre colonne. Poiché la barra di scorrimento, la larghezza del genitore e la dimensione del carattere cambiano, la larghezza di transizione effettiva cambia anche, quindi non memorizzarla in base al nome del dispositivo.

L'altezza di una scheda del 100% è il valore che riempie l'altezza degli elementi della lista nella stessa riga. Non è un'altezza fissa in pixel, quindi le righe possono crescere man mano che la descrizione aumenta. Per evitare che parole lunghe occupino troppo spazio nella dimensione dell'elemento della griglia, imposta la larghezza minima di li a 0 e usa le regole di a capo della scheda.

Aggiungi condizioni per schermo largo e movimento ridotto

Aggiungi questa sezione alla fine di style.css. A partire da 64rem inclusi, lo sfondo dell'introduzione cambia in un gradiente. La griglia continua a determinare il numero di colonne delle schede indipendentemente; questa media query non definisce tale numero.

/* Conditional adjustments */
@media (min-width: 64rem) {
  .hero { background: linear-gradient(100deg, var(--surface), #fff); }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .button { transition: none; }
}

Nella condizione di movimento ridotto, disattiviamo lo scorrimento fluido ed eliminiamo anche le transizioni del colore di sfondo. Lo scopo e il focus del collegamento e del suo contenuto sono mantenuti. L'applicazione delle regole condizionali è collegata a Media query CSS e breakpoint basati sul contenuto, e il controllo del movimento e dell'accessibilità è collegato a Verificare CSS responsive con larghezza, zoom e tastiera.

Esegui l'intero foglio di stile

Questo è un file che combina tutte le regole aggiunte passo dopo passo. Usa questo intero file per controllare l'ordine del tuo codice o per ricominciare da capo. Dopo averlo salvato nella stessa cartella di index.html, apri index.html con un browser e aggiorna la pagina.

/* Shared values and base styles */
:root {
  --ink: #183044;
  --accent: #166b92;
  --surface: #eef6fa;
  --line: #c9dbe4;
  --focus: #164f73;
}
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; color: var(--ink); font-family: sans-serif; line-height: 1.6; }
a { color: var(--accent); text-underline-offset: .15em; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.container { width: min(100% - 2rem, 68rem); margin-inline: auto; }
.container, .card { overflow-wrap: anywhere; }

/* Navigation and header */
.skip-link { position: absolute; left: 1rem; top: -6rem; padding: .5rem; background: white; }
.skip-link:focus { top: 1rem; z-index: 10; }
.site-header { border-bottom: 1px solid var(--line); }
.header-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: .5rem 1.5rem; padding-block: 1rem; }
.site-name { margin: 0; font-weight: 700; }
nav { display: flex; flex-wrap: wrap; gap: 1rem; }

/* Introduction and navigation link */
.hero { padding-block: clamp(3rem, 8vw, 6rem); background: var(--surface); }
.hero h1 { max-width: 18ch; margin-block: 0 1rem;
  font-size: clamp(1.8rem, 1.2rem + 2vw, 3rem); line-height: 1.25; }
.hero p { max-width: 50ch; }
.button { display: inline-block; margin-top: .5rem; padding: .7rem 1rem;
  border-radius: .4rem; background: var(--accent); color: white; text-decoration: none;
  transition: background-color 180ms ease; }
.button:hover { background: #104d6a; }

/* Cards and footer */
.lessons { padding-block: 3rem; }
.lessons h2 { margin-block: 0 1.5rem; }
.card-grid { display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1rem; margin: 0; padding: 0; list-style: none; }
.card-grid > li { min-width: 0; }
.card { height: 100%; padding: 1.5rem; border: 1px solid var(--line); border-radius: .5rem; }
.card h3 { margin-block: 0 .75rem; }
.card p { margin-block: 0; }
.site-footer { padding-block: 2rem; border-top: 1px solid var(--line); }
.site-footer p { margin: 0; }

/* Conditional adjustments */
@media (min-width: 64rem) {
  .hero { background: linear-gradient(100deg, var(--surface), #fff); }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .button { transition: none; }
}

Cambia i valori e diagnostica i problemi

  1. Riduci la larghezza dello schermo a circa 390px e poi aumentala, annotando i valori iniziali. Per larghezze ridotte dovrebbe esserci una colonna, per larghezze ampie dovrebbero esserci due o tre colonne. Se le condizioni descritte sopra sono uguali, confronta anche le differenze tra 559px e 560px e tra 831px e 832px.
  2. Cambia solo 16rem della griglia delle schede a 20rem. Aggiungere più colonne sulla stessa schermata richiede più spazio. Dopo la conferma, ripristina a 16rem.
  3. Cambia solo 68rem del contenitore a 50rem. Anche su schermi più grandi, la larghezza complessiva del contenuto diventa più stretta. Dopo la conferma, ripristina a 68rem.
  4. Cambia soltanto --accent, scegliendo un colore sufficientemente scuro. Verifica se gli sfondi dei link e dei pulsanti cambiano insieme e ripristina i loro colori originali. Anche il testo bianco del pulsante e l'indicatore di focus devono essere leggibili sul nuovo sfondo.
  5. Allunga la descrizione di una scheda in diverse frasi. Assicurati che il contenuto non venga troncato man mano che l'altezza aumenta e che le schede della stessa riga mantengano la stessa altezza. Dopo la pratica, ripristina la frase originale.
  6. Inserisci una stringa in inglese senza spazi nella scheda. La regola overflow-wrap: anywhere permette alla stringa di andare a capo all’interno della scheda. Rimuovere temporaneamente questa regola di interruzione della linea può provocare overflow. Dopo il confronto, sia le regole che le frasi vengono ripristinate.
  7. Spostati con Tab e Shift+Tab e premi Invio per ogni collegamento. Dovresti poter navigare all'introduzione e agli argomenti di studio senza dover usare il mouse.
  8. Emula la preferenza per il movimento ridotto. I collegamenti devono continuare a funzionare, mentre scorrimento fluido e transizioni devono essere disattivati. Dopo la verifica, ripristina l’impostazione di emulazione predefinita.

Verificare che la navigazione, le schede, gli indicatori di focus e i paragrafi rimangano leggibili quando aumenti lo zoom del browser o le impostazioni dei caratteri cambiano. L'ingrandimento temporaneo della dimensione del carattere di html negli strumenti di sviluppo verifica il ridimensionamento basato su rem, ma è diverso dallo zoom del browser. Una singola impostazione riuscita non garantisce l'usabilità in tutte le condizioni di zoom e dimensione del testo.

problema Controlla prima
Nessuno stile Estensione del file, stato del salvataggio, percorso relativo del link
Si verifica lo scorrimento orizzontale Parole lunghe, dimensione minima della colonna, larghezza effettiva del genitore, border-box mancante
Altezza della scheda irregolare Controlla altezza delle schede e degli elementi della stessa riga; righe diverse non devono avere la stessa altezza
Indicatore di focus non visibile Regole che sovrascrivono il contorno, se il contorno è tagliato a causa di overflow
Effetto di movimento indesiderato Condizioni effettive dei media e valori applicati di scroll-behavior·transition

Seleziona l'elemento problematico negli strumenti per sviluppatori per vedere la larghezza effettiva calcolata, il selettore e le colonne della Grid. Invece di mascherare il problema forzando tutti i ritorni a capo o aggiungendo overflow:hidden al body, prima correggi la dimensione e il contenuto dell'elemento in overflow. Controllando lo stato di base, lo stato modificato e lo stato di ripristino per ciascun requisito, puoi andare un passo oltre il semplice copiare il codice completato e applicarlo anche ad altri contenuti.