Passa al contenuto principale

Footer

Anteprima Reusable Footer - Layout Tre Colonne con Navigation, Social e Contacts (Screenshot Desktop)

Il Progetto

Footer è un componente React che rappresenta il mio primo esercizio non guidato dopo aver appreso le basi della sintassi JSX e della componentizzazione.

È stato estremamente utile come esercizio perché freeCodeCamp mi aveva insegnato come creare una navbar, ma non un footer. Ebbene, i concetti si tramutano con estrema similitudine: stessa logica di liste semantiche, stessa separazione tra struttura (JSX) e stile (CSS), stesso approccio dichiarativo.

Codice Sorgente

{/* DESIGN
------
* This file contains the React structure for the Footer component
* The architecture follows this semantic and functional flow:
*
* Architectural decisions (Layout strategy):
* - I realized that the original reference design (simoneamico.com) utilized a 2-column layout
* - To satisfy the strict lab constraint ("At least three unordered lists"), I logically split the
* content into "Navigation", "Social", and "Contacts"
* - This approach allows the component to pass validation tests while maintaining logical grouping
* and visual hierarchy
*
* Semantic structure (Accessibility):
* - I chose the HTML5 <footer> tag as the top-level semantic landmark
* - I encapsulated link groups in <ul> elements to ensure accessibility, as screen readers
* interpret these specifically as navigational lists
* - The copyright section is isolated in a ".footer-bottom" container to allow for separate
* spacing and styling logic
*
* Implementation details:
* - All links use href="#" placeholders as mandated by the lab requirements
* - The "footer-columns" wrapper is designed to support CSS Flexbox or Grid for responsive alignment.
*/}

{/*
* freeCodeCamp instructions:
* 1. You should export a Footer component. ✔️
* 2. Your Footer component should return a footer element. ✔️
* 3. Your Footer component should only contain a single footer element. ✔️
* 4. Your footer element should not have any siblings. ✔️
* 5. Your footer element should contain at least three unordered lists. ✔️
* 6. Each of your unordered lists should have at least two list items. ✔️
* 7. Your footer should have at least one paragraph element. ✔️
* 8. You should have a copyright (©) symbol within one of your paragraphs. ✔️
* 9. Your footer should have at least three links with the href value set to #. ✔️
* 10. None of your links should be empty. ✔️
*/}

export const Footer = () => {
return (
<footer>

{/*
* Container wrapper designed for CSS Grid/Flexbox alignment.
* Even though this lab focuses on HTML structure, this div
* prepares the layout for the 3-column responsive design.
*/}

<div className="footer-columns">

{/* Section 1: Main navigation */}
<div className="footer-section">
<h4>NAVIGAZIONE</h4>
<ul>
<li><a href="#">In Evidenza</a></li>
<li><a href="#">Percorso</a></li>
<li><a href="#">Vademecum</a></li>
<li><a href="#">Libreria</a></li>
</ul>
</div>

{/* Section 2: Social links (split from contacts to meet list quota) */}
<div className="footer-section">
<h4>SOCIAL</h4>
<ul>
<li><a href="#">Le Origini</a></li>
<li><a href="#">LinkedIn</a></li>
</ul>
</div>

{/* Section 3: Direct contacts and legal */}
<div className="footer-section">
<h4>CONTATTI</h4>
<ul>
<li><a href="#">Email</a></li>
<li><a href="#">Privacy Policy</a></li> {/* added "Privacy Policy" to satisfy "at least 2 items" rule */}
</ul>
</div>
</div>

{/* Copyright Section */}
<div className="footer-bottom">
<p>Copyright © 2026 Simone Amico.</p>
<p>Costruito con freeCodeCamp.</p>
</div>
</footer>
);
}

Design: Ibrido tra Light e Dark Mode

Ho optato per replicare il footer del sito simoneamico.com (Docusaurus), ma non volevo farlo identico perché quello già esiste.
Ho giocato su un ibrido visivo tra la modalità Light e Dark del sito: palette "Espresso & Amber" (variante dark di "Coffee & Sand"), layout a tre colonne, ma con un twist skeuomorfico che simula una "cornice in legno scuro" (#7c6148) che avvolge il "contenuto espresso" (#423121).

È stato il CSS a vestire il footer come se fosse al fondo di una card/applicazione, ma il componente stesso rimane a sé stante, mantenendo intatto il compito richiesto da freeCodeCamp: struttura semantica pura, esportabile e riutilizzabile.

Nota sul CSS condiviso: Ho mantenuto nel file anche gli stili della navbar (dal progetto precedente) per avere un design system coerente. Navbar e Footer condividono gli stessi token (colori, spacing, z-index), quindi ha senso tenerli nello stesso CSS invece di duplicare variabili. È lo stesso approccio che userei in un progetto reale.

Cosa Ho Imparato

Divide et Impera (Strategia di Layout):

  • Il design di riferimento usa un layout a 2 colonne, ma freeCodeCamp richiedeva "almeno tre liste <ul>". Ho diviso logicamente il contenuto in "Navigation", "Social" e "Contacts" per soddisfare il vincolo mantenendo gerarchia visiva e raggruppamento logico.
  • Questa scelta non è solo formale: prepara il componente per un futuro data-driven (invece di scrivere tre <ul> a mano, passerò un array di sezioni come prop e userò .map()).

Semantica HTML5 e Accessibilità:

  • Uso obbligatorio del tag <footer> come landmark semantico di primo livello (screen reader riconoscono immediatamente il contesto).
  • Liste <ul> per raggruppare link: non solo validazione freeCodeCamp, ma segnale esplicito agli assistive tech che si tratta di navigazione.
  • Separazione .footer-bottom per copyright: logica di spaziatura/styling isolata dal resto, preparando il terreno per layout responsive più complessi.

Design Token e Single Source of Truth:

  • Ho centralizzato tutto in variabili CSS :root (colori, spaziature 8pt grid, tipografia, z-index, transizioni). Modificare il tema significa toccare un solo punto, non 50 file sparsi.
  • Naming convention coerente: --color-primary, --space-md, --radius-lg. Questo prepara mentalmente al concetto di "Props" in React: invece di hardcodare valori, passi riferimenti a un sistema.

Layout Responsive (Grid Auto-Fit):

  • grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)): pattern CSS Grid che adatta automaticamente il numero di colonne in base alla larghezza disponibile. È la versione CSS del "responsive by default" di React.
  • Su mobile (@media screen and (max-width: 768px)), forzo grid-template-columns: 1fr per stack verticale. Ho anche rimosso padding del body e border-radius per passare da "app in cornice" a "esperienza nativa fullscreen".

Overflow Clipping e Border Radius:

  • overflow: hidden sul container #root è cruciale: forza navbar e footer (che hanno angoli quadrati) a rispettare il border-radius del contenitore padre, evitando l'artifact "corner bleed".
  • Questo è un pattern che tornerà utile quando dovrò gestire componenti figli che non devono "sforare" dai limiti del genitore.

Hover State con CSS puro vs React State:

  • Ho gestito il dropdown della navbar con :hover CSS (display: nonedisplay: flex). Performante e JS-free, perfetto per un lab.
  • Ma ho aggiunto un commento nel codice: "In produzione React, questo sarebbe gestito via State (isOpen)". Ho capito che CSS hover non funziona su mobile (no hover col dito) e non è controllabile via tastiera. React State risolve entrambi.

Sticky Footer Technique:

  • margin-top: auto sul footer dentro un container display: flex; flex-direction: column; min-height: 95vh: tecnica moderna per "footer appiccicato in fondo" senza posizionamento assoluto. Il footer si auto-spinge verso il basso del viewport, anche se il contenuto è poco.

Architettura CDN vs Vite (Engine Room):

  • Ho analizzato l'index.html preconfezionato da freeCodeCamp: carica React/ReactDOM via CDN (streaming) invece di bundle locale, e usa Babel Standalone come "traduttore simultaneo" che converte JSX in JS direttamente nel browser.
  • È il contrario di Vite: invece di "cuocere" il codice sul mio computer prima di inviarlo al browser, la "cottura" avviene live nel browser dell'utente. Comodo per lab, ma non scalabile in produzione (troppo overhead).

Link Placeholder (href="#") e Debito Tecnico:

  • Tutti i link usano href="#" come richiesto dal lab. Ho capito che questo è "debito tecnico intenzionale": in una SPA React vera, questi diventerebbero <Link to="/path"> (React Router) per navigazione senza ricarica.
  • Anche qui, la struttura attuale è "React-ready": basterà sostituire <a> con <Link> componente e passare le rotte come prop.

Animation FadeIn con @keyframes:

  • Dropdown menu usa animation: fadeIn 0.2s invece di solo transition, perché voglio controllare sia opacità CHE transform (translateY). Transition gestisce solo proprietà singole che cambiano, Keyframes orchestrano sequenze.

Mobile-First Mindset:

  • Ho scritto CSS desktop-first (per comodità visiva durante sviluppo), ma ho capito che in produzione si parte da mobile (@media (min-width: 768px)) per Progressive Enhancement. Ora che ho visto entrambi gli approcci, capisco perché mobile-first è standard.

Riflessioni

Ormai sai che è sempre così: quando faccio esercizi non guidati come i Certification Project o questi Labs (che di fatto sono Certification Project con index.html preconfezionato), trovo poco da dire nei README proprio perché ho detto tutto nel codice sorgente nei vari commenti.


Next:
Imparare a lavorare con Props, Conditional Rendering e Lists in React, per poi applicare tutto nel Profile Card Component.