The footer provides essential site information, links, and contact details. It uses CSS Grid for a responsive multi-column layout that adapts to different screen sizes.
What You’ll Build
Multi-column grid layout
Contact information with semantic HTML
Link lists
Social media icons
Copyright and legal information
Building the HTML
Create the Footer Element
Start with a semantic <footer> element: < footer class = "footer" id = "main-footer" >
< div class = "footer__container" >
<!-- Content goes here -->
</ div >
</ footer >
Create the Grid Container
Add a grid for multiple columns: < div class = "footer__grid" >
<!-- Columns go here -->
</ div >
Add About Column
First column with company info: < div class = "footer__column" >
< h4 class = "footer__column-title" > Sobre ML Store </ h4 >
< address class = "footer__address" >
< p > Tu tienda de confianza desde 2024 </ p >
< p > Contacto: [email protected] </ p >
</ address >
</ div >
The <address> element is semantic HTML for contact information. It doesn’t mean physical address - it’s for any contact info.
Add Links Column
Second column with useful links: < div class = "footer__column" >
< h4 class = "footer__column-title" > Enlaces útiles </ h4 >
< ul class = "footer__links" >
< li >< a href = "#" class = "footer__link" > Cómo comprar </ a ></ li >
< li >< a href = "#" class = "footer__link" > Métodos de pago </ a ></ li >
< li >< a href = "#" class = "footer__link" > Envíos </ a ></ li >
< li >< a href = "#" class = "footer__link" > Devoluciones </ a ></ li >
</ ul >
</ div >
Add Social Media Column
Third column with social icons: < div class = "footer__column" >
< h4 class = "footer__column-title" > Síguenos </ h4 >
< div class = "footer__social" >
< a href = "#" class = "footer__social-link" aria-label = "Facebook" > 📘 </ a >
< a href = "#" class = "footer__social-link" aria-label = "Twitter" > 🐦 </ a >
< a href = "#" class = "footer__social-link" aria-label = "Instagram" > 📷 </ a >
< a href = "#" class = "footer__social-link" aria-label = "YouTube" > ▶️ </ a >
</ div >
</ div >
Accessibility : aria-label describes icon-only links for screen readers.
Add Divider and Bottom Section
Separate footer from bottom copyright: < hr class = "footer__divider" />
< div class = "footer__bottom" >
< small class = "footer__copyright" >
© 2024 ML Store. Todos los derechos reservados.
</ small >
< small class = "footer__legal" >
Este es un proyecto educativo - Tutorial HTML, CSS y TypeScript
</ small >
</ div >
<small> is semantic HTML for “fine print” like copyright notices and legal disclaimers.
< footer class = "footer" id = "main-footer" >
< div class = "footer__container" >
< div class = "footer__grid" >
<!-- Column 1: About -->
< div class = "footer__column" >
< h4 class = "footer__column-title" > Sobre ML Store </ h4 >
< address class = "footer__address" >
< p > Tu tienda de confianza desde 2024 </ p >
< p > Contacto: [email protected] </ p >
</ address >
</ div >
<!-- Column 2: Links -->
< div class = "footer__column" >
< h4 class = "footer__column-title" > Enlaces útiles </ h4 >
< ul class = "footer__links" >
< li >< a href = "#" class = "footer__link" > Cómo comprar </ a ></ li >
< li >< a href = "#" class = "footer__link" > Métodos de pago </ a ></ li >
< li >< a href = "#" class = "footer__link" > Envíos </ a ></ li >
< li >< a href = "#" class = "footer__link" > Devoluciones </ a ></ li >
</ ul >
</ div >
<!-- Column 3: Social -->
< div class = "footer__column" >
< h4 class = "footer__column-title" > Síguenos </ h4 >
< div class = "footer__social" >
< a href = "#" class = "footer__social-link" aria-label = "Facebook" > 📘 </ a >
< a href = "#" class = "footer__social-link" aria-label = "Twitter" > 🐦 </ a >
< a href = "#" class = "footer__social-link" aria-label = "Instagram" > 📷 </ a >
< a href = "#" class = "footer__social-link" aria-label = "YouTube" > ▶️ </ a >
</ div >
</ div >
</ div >
< hr class = "footer__divider" />
< div class = "footer__bottom" >
< small class = "footer__copyright" >
© 2024 ML Store. Todos los derechos reservados.
</ small >
< small class = "footer__legal" >
Este es un proyecto educativo - Tutorial HTML, CSS y TypeScript
</ small >
</ div >
</ div >
</ footer >
Styling with CSS
Main Footer Block
.footer {
background-color : var ( --color-white );
padding : var ( --spacing-2xl ) var ( --spacing-lg ) var ( --spacing-lg );
margin-top : auto ; /* Pushes footer to bottom if content is short */
}
.footer__container {
max-width : var ( --container-max-width );
margin : 0 auto ;
}
margin-top: auto - When used in a flex container, this pushes the footer to the bottom of the page even if there’s not much content.
Grid Layout
.footer__grid {
display : grid ;
grid-template-columns : repeat ( auto-fit , minmax ( 200 px , 1 fr ));
gap : var ( --spacing-xl );
margin-bottom : var ( --spacing-xl );
}
Grid breakdown:
repeat(auto-fit, ...) - Creates as many columns as will fit
minmax(200px, 1fr) - Each column is minimum 200px, maximum 1fr
Automatically responsive:
Mobile (320px): 1 column
Tablet (768px): 2-3 columns
Desktop (1200px): 3 columns side-by-side
auto-fit vs auto-fill : With auto-fit, empty columns collapse and existing columns expand. This is perfect for footers where you want columns to be evenly sized.
Column Styling
.footer__column-title {
font-size : var ( --font-size-base );
font-weight : 600 ;
color : var ( --color-gray-600 );
margin-bottom : var ( --spacing-md );
}
Address Styling
.footer__address {
font-style : normal ; /* Override default italic */
color : var ( --color-gray-500 );
font-size : var ( --font-size-sm );
line-height : 1.8 ; /* Extra line height for readability */
}
font-style: normal - The <address> element defaults to italic. We override this for a cleaner look.
Links Column
.footer__links {
display : flex ;
flex-direction : column ; /* Stack vertically */
gap : var ( --spacing-sm );
}
.footer__link {
font-size : var ( --font-size-sm );
color : var ( --color-gray-500 );
transition : color var ( --transition-fast );
}
.footer__link:hover {
color : var ( --color-secondary ); /* Blue on hover */
}
flex-direction: column - Flexbox defaults to row (horizontal). We change it to column for vertical stacking.
.footer__social {
display : flex ;
gap : var ( --spacing-md );
}
.footer__social-link {
font-size : var ( --font-size-xl ); /* Larger icons */
transition : transform var ( --transition-fast );
}
.footer__social-link:hover {
transform : scale ( 1.2 ); /* Grow 20% on hover */
}
Divider
.footer__divider {
border : none ; /* Remove default border */
height : 1 px ;
background-color : var ( --color-gray-200 );
margin : var ( --spacing-xl ) 0 ;
}
Custom HR : We remove the default border and use background-color for a cleaner, more controllable line.
Bottom Section
.footer__bottom {
display : flex ;
justify-content : space-between ;
align-items : center ;
flex-wrap : wrap ; /* Stack on narrow screens */
gap : var ( --spacing-md );
padding-top : var ( --spacing-md );
}
.footer__copyright ,
.footer__legal {
font-size : var ( --font-size-xs );
color : var ( --color-gray-400 );
}
flex-wrap: wrap - On narrow screens, copyright and legal text will stack vertically instead of being squished.
HTML Entities
The copyright symbol uses an HTML entity:
Rendered as: © 2024 ML Store
Common HTML Entities
Entity Symbol Description ©© Copyright ®® Registered trademark ™™ Trademark €€ Euro currency ££ Pound currency ¥¥ Yen currency Non-breaking space << Less than >> Greater than && Ampersand "” Quotation mark
Responsive Behavior
Mobile (< 600px)
+---------------------------+
| Sobre ML Store |
| Address info here |
+---------------------------+
| Enlaces útiles |
| - Link 1 |
| - Link 2 |
+---------------------------+
| Síguenos |
| 📘 🐦 📷 ▶️ |
+---------------------------+
Columns stack vertically.
Tablet (600px - 900px)
+-------------+-------------+
| Sobre ML | Enlaces |
| Store | útiles |
+-------------+-------------+
| Síguenos |
+---------------------------+
Two columns, third wraps below.
Desktop (> 900px)
+---------+---------+---------+
| Sobre | Enlaces | Síguenos|
| ML | útiles | |
| Store | | |
+---------+---------+---------+
Three equal columns.
To make the footer stick to the bottom even on short pages, use flexbox on the body:
body {
min-height : 100 vh ; /* Full viewport height */
display : flex ;
flex-direction : column ;
}
main {
flex : 1 ; /* Takes all available space */
}
footer {
margin-top : auto ; /* Pushes to bottom */
}
How it works:
Body is a flex container with column direction
Main content grows to fill available space
Footer stays at the bottom
Accessibility Features
Semantic Elements - Using <footer>, <address>, <small> for proper meaning
aria-label - Describing icon-only links for screen readers
Heading Hierarchy - Using <h4> since it’s inside a section (proper nesting)
Focus Indicators - All links have visible focus states
Color Contrast - Text meets WCAG AA standards against background
Complete Code Reference
HTML : /workspace/source/mi-tutorial/index.html:725-805
CSS : /workspace/source/mi-tutorial/src/style.css:1358-1423
Enhancement Ideas
< div class = "footer__column" >
< h4 class = "footer__column-title" > Newsletter </ h4 >
< form class = "footer__newsletter" >
< input
type = "email"
placeholder = "Tu email"
required
/>
< button type = "submit" > Suscribirse </ button >
</ form >
</ div >
Replace emoji with proper SVG icons: < a href = "#" class = "footer__social-link" aria-label = "Facebook" >
< svg width = "24" height = "24" viewBox = "0 0 24 24" fill = "currentColor" >
< path d = "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z" />
</ svg >
</ a >
Next Steps
API Integration Learn how to fetch data from external APIs
State Management Understand centralized application state