Use the simplest tool that solves the problem
-
Center text with
text-align - Center a block with auto margins
- Use flex when you are actually controlling layout between children
Best practices help you write clean, maintainable, and scalable code. They reduce bugs, improve readability, and help you build strong habits early.
Before you move on, ask:
Is the structure clean?
Are names clear?
Are images handled properly?
Is spacing consistent?
Is this readable later?
These are everyday rules that help build strong habits in HTML and CSS.
| Rule | Description | Example |
|---|---|---|
| Always set position before using z-index | z-index only works on positioned elements. | .box { position: relative; z-index: 10; } |
| Use small, meaningful z-index values | Large numbers create stacking chaos. | Modal: 100, Overlay: 1000 |
| Always include alt text | Required for accessibility and SEO. | <img src="cat.jpg" alt="Grey cat"> |
| Use correct image formats | Choose formats based on content type. | SVG for icons, JPG for photos |
| Always set size, position, repeat for background images | Prevents stretching, tiling, and misalignment. |
background-size: cover;
background-position: center; background-repeat: no-repeat; |
| Use flexbox or grid for layout | Do not build page layout with absolute positioning. | display: flex; |
| Use max-width for readable text | Stops lines from becoming too long. | max-width: 62.5rem; |
| Use a spacing scale | Creates visual consistency. | 4px, 8px, 16px, 24px, 32px |
| Use rem for font sizes | Improves accessibility and scaling. | font-size: 1.25rem; |
| Use responsive units | Helps layouts adapt better across screens. | font-size: clamp(1rem, 2vw, 2rem); |
Good code should be:
clear
consistent
easy to scan
easy to return to later
| Practice | Description | Good Example | Avoid |
|---|---|---|---|
| Keep HTML tidy | Clean structure makes debugging easier. | <div class="card">...</div> | messy nesting and inconsistent spacing |
| Close tags properly | Broken structure causes layout problems. | <li>Item</li> | <li>Item |
| Use lowercase and quotes | Keeps HTML consistent and readable. | <a href="page.html"> | <A href='page.html'> |
| Indent consistently | Makes structure easier to read. | nested elements line up clearly | random indentation |
If the HTML looks messy,
the CSS will usually become messy too.
Consistent naming makes code easier to read and maintain.
| Convention | Description | Example |
|---|---|---|
| kebab-case | Used for CSS classes and HTML files. | .main-header |
| camelCase | Used for JavaScript variables. | let userName = "Alan"; |
| PASCALCase | Used for JS classes and React components. | class UserProfile {} |
Name things by purpose,
not by appearance.
Better:
.gallery-item
Weaker:
.blue-box-left
text-align
Headings should represent structure and hierarchy. Captions and supporting text are usually better as paragraphs.
This makes it easier to debug and keeps flex rules from affecting unrelated elements.
If the body already sets the base font, repeated font classes may be unnecessary.
If an element has a max-width and should stay centred on wide screens, it usually also needs auto margins.
Accessibility means designing so that everyone can use your site — including users with visual impairments, colour blindness, or who rely on assistive technologies like screen readers. The W3C Web Accessibility Initiative developed ARIA (Accessible Rich Internet Applications) — a set of HTML attributes that add context and meaning for screen readers. Accessible sites are also clearer, more structured, and easier to maintain.
| Practice | Description | Example |
|---|---|---|
| Alt text | Added to <img> and similar elements. Screen readers read it aloud. Also displays on screen if the image fails to load. Max 150 characters. | <img alt="A red car"> |
| Semantic HTML | Use meaningful tags so screen readers understand the page structure. <header> tells a screen reader this is the header — <div id="header"> does not. | <header> not <div id="header"> |
| ARIA role | The role attribute tells a screen reader what an element's purpose is. Landmark roles define the regions of a page (header, nav, main, etc.) — not the organisational structure of content within those regions. role="main" can only be used once per page, just like <main> itself. | role="complementary" |
| role="presentation" | Tells the screen reader to skip the element — use for purely decorative images or non-informational wrappers. role="none" is the modern equivalent. | <img src="border.png" role="none"> |
| aria-label | Adds a text description for screen readers on any element. Unlike alt, it is never displayed on screen. Use when there is no visible text label to rely on. | <p aria-label="Artist">...</p> |
| aria-labelledby | Points to another element by its id to use as the label. The value must exactly match the id of the labelling element — not a class, not a made-up name. | <header aria-labelledby="title"> ... <h2 id="title"> |
| Keyboard navigation | Ensure interactive elements are focusable. | button:focus { outline: 2px solid; } |
| Heading order | Use one h1 per page — it defines the page purpose. Don't skip levels. Headings aid navigation, screen readers, and SEO. | h1 → h2 → h3 (never skip) |
| Labels for forms | Always use <label> — don't rely on placeholder text alone as it is often low contrast and not read by all screen readers. | <label for="email">Email</label> |
| Real text not images of text | Screen readers can read real text. Images of text can't be scaled without losing quality and are slower to load. | use <p> not <img> for text |
| Colour contrast | WCAG minimum ratio: 4.5:1 for standard text, 3:1 for large text (24px+). Black on white gives maximum contrast but can cause glare. | #000 on #fff = 21:1 |
| Font size | Standard browser default is 16px. Use at least 1rem for body text. Smaller sizes should be reserved for non-essential content only. | font-size: 1rem minimum |
| Don't rely on colour alone | About 8% of men and 0.5% of women have colour blindness. Pair colour with text or icons. Never use colour as the only indicator. | error icon + red + "Invalid email" |
alt vs aria-label:
→ alt — use on <img> and elements that support it; displays on screen if image fails to load
→ aria-label — use on any element; never displays on screen; better for elements that don't support alt
alt attribute conventions:
→ Concisely describe the image (what it shows, not "image of...")
→ For a linked image, describe where the link goes
→ For a decorative image, use alt="" (empty) — never omit the attribute entirely
→ If the image is already described by nearby text, use alt="" to avoid repeating it
→ Maximum 150 characters
| Screen Reader | Platform | How to access |
|---|---|---|
| VoiceOver | macOS (built in) | Command + F5 to toggle on/off |
| NVDA | Windows (free, open source) | Download from nvaccess.org |
| ChromeVox | Chrome browser (any OS) | Add from Chrome Web Store as an extension |
Colour blindness — practical steps:
→ Use high contrast colours (opposite on the colour wheel)
→ Use multiple shades of brightness so differences survive grayscale
→ Always pair colour with text or icons to convey meaning
Design trend watch — common accessibility pitfalls:
→ Text over images: low contrast — add a dark transparent overlay to fix
→ Removing input labels: placeholder text is often low contrast and not screen-reader reliable — keep labels
→ Flat buttons/links: don't use colour alone to show something is clickable — use shape, underline, or icons too
| Practice | Description | Example |
|---|---|---|
| Use clear file names | Makes assets easier to find and manage. | shoreline-waves-header.jpg |
| Group files by type | Keeps projects organised. | /images /css /html |
| Use correct relative paths | Prevents broken assets and links. | ./images/photo.jpg |
Good project structure saves time later.
Messy folders create unnecessary bugs.
| Practice | Description | Example |
|---|---|---|
| Choose the right format | Different assets suit different formats. | JPG for photos, SVG for icons |
| Use background images intentionally | Good for decoration, not meaningful content. | hero/banner backgrounds |
| Compress large images | Helps performance without obvious quality loss. | optimised web image |
| Control image fit | Prevent distortion and awkward cropping. | object-fit: cover; |
Rule:
Container first
Image second
Do not let the image accidentally control the layout.
| Practice | Description | Example |
|---|---|---|
| Pair labels with inputs | Improves usability and accessibility. | <label for="name">Name</label> |
| Use correct input types | Helps validation and mobile keyboards. | <input type="email"> |
| Use placeholders carefully | Do not rely on them instead of labels. | placeholder is support, not structure |
Good forms are:
clear
labelled
easy to use
| Practice | Description | Example |
|---|---|---|
| Optimise images | Large files slow pages down. | compress before upload |
| Avoid deep nesting | Too much nesting makes HTML harder to manage. | keep structure shallow where possible |
| Keep the DOM clean | Use only the elements you need. | avoid unnecessary wrappers |
Simple code is often:
faster
cleaner
easier to debug
| Mistake | Why it causes problems | Better Approach |
|---|---|---|
| Using <br> for spacing | Breaks structure and makes spacing inconsistent. | Use margin or padding |
| Too many divs | Makes structure harder to understand. | Use semantic elements where possible |
| Inline CSS everywhere | Harder to maintain and reuse. | Use external CSS |
| Missing alt text | Hurts accessibility. | Add meaningful descriptions |
| Naming by appearance | Becomes confusing when design changes. | Name by role or purpose |
If a habit creates mess later,
it is probably not a best practice now.
Keep HTML clean
Name clearly
Use semantic structure
Style the right element
Control the container first
Use spacing intentionally
Optimise images
Keep code readable later