HTML & CSS Essentials for AI-Assisted Development

Generate, Verify & Improve AI-Generated Markup

Université de Toulon

LIS UMR CNRS 7020

2025-10-12

Welcome to Modern HTML/CSS

Important

New Approach: This isn’t a comprehensive HTML/CSS tutorial. Instead, we’ll focus on the essential knowledge you need to verify and improve AI-generated code.

You already have AI tools! Use them to generate HTML/CSS, but you must understand what they create.

Learning Objectives

By the end of this session, you will be able to:

  • Identify semantic HTML and why it matters
  • Verify accessibility in AI-generated HTML
  • Understand CSS selectors, specificity, and the box model
  • Evaluate responsive design patterns
  • Spot common issues in AI-generated markup
  • Improve generated code for production quality

Part 1: HTML — Why Semantic HTML Matters

AI often generates <div> soup — functionally correct but semantically wrong.

❌ What AI Might Generate

<div class="header">
  <div class="nav">
    <div class="nav-item">Home</div>
    <div class="nav-item">About</div>
  </div>
</div>
<div class="content">
  <div class="article">
    <div class="title">My Article</div>
    <div class="text">Lorem ipsum...</div>
  </div>
</div>

Problems:

  • No semantic meaning
  • Poor SEO
  • Inaccessible to screen readers
  • Harder to maintain

✅ Semantic Version

<header>
  <nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
  </nav>
</header>
<main>
  <article>
    <h1>My Article</h1>
    <p>Lorem ipsum...</p>
  </article>
</main>

Benefits:

  • ✅ Clear document structure
  • ✅ Better SEO
  • ✅ Accessible
  • ✅ Maintainable

Essential HTML5 Semantic Elements

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Page Title</title>
</head>
<body>
  <header>   <!-- Page/section header -->
    <nav>    <!-- Navigation links -->
      <!-- navigation links go here -->
    </nav>
  </header>

  <main>     <!-- Main content (ONE per page) -->
    <article>  <!-- Self-contained content -->
      <section>  <!-- Thematic grouping -->
        <!-- section content -->
      </section>
    </article>
    <aside>    <!-- Sidebar/related content -->
      <!-- aside content -->
    </aside>
  </main>

  <footer>   <!-- Page/section footer -->
    <!-- footer content -->
</body>
</html>

Common AI Mistakes

  1. Multiple <main> elements — Only ONE allowed per page!
  2. No heading hierarchy — Skipping from h1 to h4 confuses screen readers
  3. Generic <div> everywhere — Use semantic elements first, divs for styling only

Verification Checklist: Semantic HTML

When AI generates HTML, verify these critical points:

✅ Structure

✅ Accessibility

✅ SEO & Meta Tags

Live Demo: Fixing AI-Generated HTML

Scenario: AI generates a product card. Let’s review and improve it.

AI’s First Attempt

<div class="product-card">
  <img src="phone.jpg">
  <div class="product-name">iPhone 15</div>
  <div class="price">$999</div>
  <div class="button">Buy Now</div>
</div>

What’s wrong? (Identify with class)

  • Missing alt text
  • No semantic elements
  • Button is a div (not interactive)
  • No price semantics

Improved Version

<article class="product-card">
  <img src="phone.jpg" alt="iPhone 15 in blue color">
  <h2>iPhone 15</h2>
  <p class="price">
    <span class="sr-only">Price:</span>
    <data value="999">$999</data>
  </p>
  <button type="button">Buy Now</button>
</article>

Improvements:

  • <article> (self-contained product)
  • <h2> (semantic heading)
  • <data> element (machine-readable price)
  • ✅ Real <button> (keyboard accessible)
  • ✅ Alt text (descriptive)
  • ✅ Screen-reader text for “Price”

Screen-reader helper (CSS)

Add a utility class for visually-hidden text used for assistive technologies (used above as .sr-only).

.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

Use .sr-only for labels or helper text that should be read by screen readers but not shown visually.

Prompting Tip

Instead of: “Create a product card”

Try: “Create a semantic HTML product card with proper accessibility. Include article element, heading, alt text for images, and a real button element.”

Notes:

  • Skip links should be first focusable element and become visible on :focus.
  • Prefer aria-label or a visible heading inside landmarks to give assistive tech a name.
  • Avoid adding ARIA roles that duplicate native elements (don’t add role="navigation" to a <nav> unless you need to override semantics).
  • Use aria-hidden="true" for purely decorative content so screen readers ignore it.

Prompting tip for LLMs: “Return semantic HTML with ARIA where necessary. Include a skip-link and explicit aria-labels on landmarks. Explain any ARIA you add and why native semantics couldn’t cover it.”

Responsive Images & Lazy-loading

When AI generates image markup it often forgets responsive sources, width/height, and lazy-loading : this harms performance and causes layout shifts.

Basic responsive img with srcset/sizes and lazy loading:

<img
  src="/images/phone-800.jpg"
  srcset="/images/phone-400.jpg 400w, /images/phone-800.jpg 800w, /images/phone-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw, 50vw"
  width="800" height="600"
  loading="lazy"
  decoding="async"
  alt="iPhone 15 in blue color">

Use <picture> for format selection or art-direction (e.g., WebP fallback or different crops):

<picture>
  <source type="image/webp" srcset="/images/phone-800.webp 800w, /images/phone-1200.webp 1200w" sizes="(max-width:600px) 100vw, 50vw">
  <img src="/images/phone-800.jpg" srcset="/images/phone-800.jpg 800w, /images/phone-1200.jpg 1200w" sizes="(max-width:600px) 100vw, 50vw" loading="lazy" width="800" height="600" alt="iPhone 15 in blue color">
</picture>

Best practices to include in verification:

  • Always include alt (or alt="" for purely decorative images) and a sensible width/height or CSS aspect-ratio to avoid layout shift.
  • Use loading="lazy" for non-critical images, decoding="async" for faster paint.
  • Prefer srcset/sizes or <picture> for large images so browsers select appropriate resources.
  • Validate generated image paths and ensure optimized assets exist (AI may invent filenames).

Prompting tip for LLMs: “Generate image markup with srcset, sizes, width/height, loading=”lazy”, and a brief note about expected image file names and sizes. If the image is decorative, set alt=“” and aria-hidden as needed.”

Part 2: CSS Essentials for Verification

You must understand these to verify AI-generated CSS:

  1. Selectors — How to target elements
  2. Specificity — Which styles win when there’s conflict
  3. Box Model — How spacing works

CSS Basic Selectors

/* Element selector */
p { color: blue; }

/* Class selector (most common) */
.highlight { background: yellow; }

/* ID selector (use sparingly) */
#header { position: fixed; }

/* Attribute selector */
[type="text"] { border: 1px solid gray; }

CSS Combinators

/* Descendant (any level) */
.card p { margin: 0; }

/* Direct child only */
.card > p { margin: 0; }

/* Adjacent sibling */
h2 + p { font-weight: bold; }

/* General sibling */
h2 ~ p { color: gray; }

Pseudo-classes (State-based)

/* User interactions */
a:hover { color: red; }
a:focus { outline: 2px solid blue; }
button:active { transform: scale(0.95); }

/* Position-based */
li:first-child { font-weight: bold; }
li:last-child { margin-bottom: 0; }
li:nth-child(odd) { background: #f0f0f0; }

CSS Specificity

Specificity determines which style wins when multiple rules target the same element.

Specificity Hierarchy (from weakest to strongest):

  • Element selectors (div, p, h1)
  • Class selectors (.card, .btn)
  • Attribute selectors and pseudo-classes ([type=“text”], :hover)
  • ID selectors (#header)
  • Inline styles (style=“…”)
  • !important (avoid in production — overrides everything)

Example: Which style wins?

CSS rules:

/* Specificity: (1 element) */
p { color: blue; }

/* Specificity: (1 class) - WINS! */
.text { color: red; }

/* Specificity: (1 class + 1 element) - WINS OVER .text! */
p.text { color: green; }

/* Specificity: (1 ID) - WINS OVER EVERYTHING! */
#intro { color: purple; }

HTML example:

<p class="text" id="intro">What color is this?</p>
<!-- Answer: PURPLE (ID has highest specificity) -->

Common AI Mistake: Overusing IDs

AI might generate:

#button1 { background: blue; }
#button2 { background: blue; }
#button3 { background: blue; }

Problem: Not reusable, high specificity

Better approach:

.btn-primary { background: blue; }

The Box Model: Understanding Spacing

Every element is a box with 4 layers:

┌─────────────────────────────────┐
│ MARGIN (transparent)            │
│  ┌───────────────────────────┐  │
│  │ BORDER                    │  │
│  │  ┌─────────────────────┐  │  │
│  │  │ PADDING             │  │  │
│  │  │  ┌───────────────┐  │  │  │
│  │  │  │   CONTENT     │  │  │  │
│  │  │  │  (text, img)  │  │  │  │
│  │  │  └───────────────┘  │  │  │
│  │  └─────────────────────┘  │  │
│  └───────────────────────────┘  │
└─────────────────────────────────┘

Box Model Properties

.box {
  /* Content size */
  width: 200px;
  height: 100px;
  
  /* Spacing inside the border */
  padding: 20px;           /* All sides */
  padding: 10px 20px;      /* vertical | horizontal */
  padding: 10px 20px 30px; /* top | horizontal | bottom */
  
  /* Border */
  border: 2px solid black;
  
  /* Spacing outside the border */
  margin: 20px;
  margin: 0 auto;          /* Center horizontally */
}

Box-Sizing: Critical for Layout

/* Default behavior (confusing!) */
.box {
  width: 200px;
  padding: 20px;
  border: 2px solid;
  /* Total width = 200 + 20*2 + 2*2 = 244px! */
}

/* Modern best practice (include padding/border in width) */
* {
  box-sizing: border-box;
}

.box {
  width: 200px;
  padding: 20px;
  border: 2px solid;
  /* Total width = 200px (padding and border included) */
}

Always Include in Your Projects

/* At the top of your CSS file */
*, *::before, *::after {
  box-sizing: border-box;
}

AI often forgets this! Add it manually.

CSS Verification Checklist

When AI generates CSS, check:

✅ Selectors

✅ Layout

✅ Accessibility

Part 3: Responsive Design Patterns - Mobile-First Approach

Modern standard: Design for mobile, enhance for desktop.

Mobile-First Media Queries

/* Base styles (mobile) */
.container {
  width: 100%;
  padding: 10px;
}

/* Tablet and up (min-width = mobile-first) */
@media (min-width: 768px) {
  .container {
    max-width: 720px;
    margin: 0 auto;
  }
}

/* Desktop and up */
@media (min-width: 1024px) {
  .container {
    max-width: 960px;
  }
}

AI Often Does Desktop-First!

Watch for max-width media queries (desktop-first):

/* Desktop styles (default) */
.sidebar { width: 300px; }

/* Then mobile */
@media (max-width: 768px) {
  .sidebar { width: 100%; }
}

Important

Ask AI to rewrite as mobile-first!

Flexbox: The Modern Layout Tool

Use Flexbox for one-dimensional layouts (rows or columns).

/* Parent container */
.flex-container {
  display: flex;
  flex-direction: row;      /* or column */
  justify-content: center;  /* align on main axis */
  align-items: center;      /* align on cross axis */
  gap: 20px;                /* spacing between items */
}

/* Child items */
.flex-item {
  flex: 1;  /* Grow to fill space equally */
}

Common Patterns

/* Horizontal navigation */
nav {
  display: flex;
  gap: 20px;
}

/* Centered content */
.hero {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

/* Card layout (wrap on small screens) */
.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 1 1 300px; /* grow | shrink | basis */
}

CSS Grid: Two-Dimensional Layouts

Use Grid for complex two-dimensional layouts.

Basic Grid Pattern

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
  gap: 20px;
}

/* Responsive grid (auto-fit) */
.responsive-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

When to Use What?

  • Flexbox: Navigation bars, button groups, simple card layouts
  • Grid: Page layouts, complex card grids, dashboard layouts
  • Both: Nest Flexbox inside Grid cells!

Tailwind CSS: AI’s Favorite Framework

Traditional CSS

<style>
.card {
  padding: 1.5rem;
  background: white;
  border-radius: 0.5rem;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
</style>
<div class="card">Content</div>

Tailwind = Utility-first CSS framework

Instead of writing CSS, use pre-built classes:

Tailwind Approach

<div class="p-6 bg-white rounded-lg shadow-md">
  Content
</div>

Tailwind pros & cons

Pros:

  • ✅ Fast prototyping (AI loves this!)
  • ✅ No naming decisions
  • ✅ Responsive utilities built-in
  • ✅ Consistent design system

Cons:

  • ❌ HTML gets cluttered
  • ❌ Learning curve for utilities
  • ❌ Harder to scan visually

Essential Tailwind Classes

Spacing (m=margin, p=padding, numbers = 4px units)

<div class="m-4">      margin: 1rem (16px)
<div class="p-6">      padding: 1.5rem (24px)
<div class="mx-auto">  margin-left/right: auto (center)
<div class="mt-2">     margin-top: 0.5rem

Layout

<div class="flex items-center justify-between">
<div class="grid grid-cols-3 gap-4">
<div class="w-full md:w-1/2">  width: 100% on mobile, 50% on md+

Typography

<h1 class="text-3xl font-bold text-gray-900">
<p class="text-base text-gray-600 leading-relaxed">

Colors (gray, red, blue, green, etc. with shades 50-900)

<div class="bg-blue-500 text-white">
<div class="bg-gray-100 text-gray-900">
<div class="hover:bg-blue-600">  darker blue on hover

Responsive Prefixes (sm, md, lg, xl, 2xl)

<div class="text-sm md:text-base lg:text-lg">
<!-- Small on mobile, base on tablet, large on desktop -->

AI + Tailwind = Perfect Match

When prompting AI for Tailwind:

"Create a product card using Tailwind CSS with:
- White background with shadow
- Padding and rounded corners
- Responsive (full width on mobile, 1/3 on desktop)
- Hover effect on image"

AI will generate Tailwind classes correctly most of the time!

Part 4: Common AI Mistakes & How to Fix Them

🚩 Problem 1: Inline Styles Everywhere

<!-- ❌ AI might generate -->
<div style="background: blue; padding: 20px; margin: 10px;">
  <p style="color: white; font-size: 16px;">Text</p>
</div>

Why bad? Not reusable, hard to maintain, poor separation of concerns

Fix: Use classes

<!-- ✅ Better -->
<div class="card">
  <p class="card-text">Text</p>
</div>

<style>
.card { background: blue; padding: 20px; margin: 10px; }
.card-text { color: white; font-size: 16px; }
</style>

🚩 Problem 2: No Alt Text or Generic Alt

<!-- ❌ AI might generate -->
<img src="product.jpg">
<img src="product.jpg" alt="image">
<img src="product.jpg" alt="product image">

Why bad? Screen readers can’t describe the image

Fix: Descriptive alt text

<!-- ✅ Better -->
<img src="product.jpg" alt="iPhone 15 Pro in titanium blue finish">

Prompt fix: “Ensure all images have descriptive alt text explaining what’s shown”

🚩 Problem 3: Fake Buttons (Divs with Click Handlers)

<!-- ❌ AI might generate -->
<div class="button" onclick="buy()">Buy Now</div>

Why bad? - Not keyboard accessible (can’t Tab to it) - No focus indicator - Screen readers don’t announce it as a button - No Enter/Space key support

Fix: Real button elements

<!-- ✅ Better -->
<button type="button" onclick="buy()">Buy Now</button>

🚩 Problem 4: CSS Without box-sizing

/* ❌ AI often forgets */
.card {
  width: 300px;
  padding: 20px;
  border: 2px solid;
  /* Actual width = 344px! */
}

Fix: Add box-sizing globally

/* ✅ Add at top of CSS file */
*, *::before, *::after {
  box-sizing: border-box;
}

🚩 Problem 5: No Focus Styles

/* ❌ AI might only style hover */
button:hover {
  background: darkblue;
}

Why bad? Keyboard users can’t see where they are

Fix: Always include focus styles

/* ✅ Better */
button:hover,
button:focus {
  background: darkblue;
}

button:focus {
  outline: 2px solid blue;
  outline-offset: 2px;
}

🚩 Problem 6: Hardcoded Pixel Values Everywhere

/* ❌ AI loves px */
.container {
  width: 1200px;
  padding: 20px;
  margin: 30px;
}

Why bad? Not responsive, doesn’t scale with user’s font preferences

Fix: Use relative units

/* ✅ Better */
.container {
  max-width: 75rem;    /* 1200px at default font size */
  padding: 1.25rem;    /* Scales with font size */
  margin: 0 auto;      /* Center horizontally */
}

Unit guide:

  • rem — Relative to root font size (best for spacing)
  • em — Relative to parent font size (good for padding inside text)
  • % — Relative to parent element (good for widths)
  • vw/vh — Relative to viewport (good for full-screen sections)

Your Verification Workflow

Every time AI generates HTML/CSS:

  • Step 1: Read & Understand (Don’t just copy!)

    • What is this code trying to do?
    • Are there semantic elements or just divs?
  • Step 2: Check Semantics

  • Step 3: Check Accessibility

  • Step 4: Check CSS Quality

  • Step 5: Test in Browser

Summary & Key Takeaways

Remember These Always

  1. Semantic HTML first — Then style with CSS
  2. Accessibility is not optional — Alt text, labels, focus states
  3. Mobile-first responsive — Start small, enhance for large screens
  4. AI generates, you verify — Never copy-paste without understanding
  5. Test in real browsers — DevTools + keyboard navigation + Lighthouse

Prompt Templates for Practice

Now you try! Use these prompts with your AI tool of choice.

For HTML Generation

Create semantic HTML for a product review card with:
- Article element as container
- Product image with descriptive alt text
- Heading for reviewer name
- Star rating (5 stars, accessible)
- Review text paragraph
- Date element with machine-readable format
- Helpful/Not helpful buttons (real button elements)

Ensure proper accessibility with ARIA labels where needed.

For Tailwind CSS Styling

Style the review card using Tailwind CSS with:
- White background with subtle shadow
- Rounded corners and padding
- Responsive layout (full width on mobile, 1/3 on desktop)
- Hover effect (slight shadow increase)
- Focus states for buttons
- Mobile-first approach with sm:, md:, lg: breakpoints

For Verification

Review this HTML/CSS code for:
- Semantic HTML correctness
- Accessibility issues (alt text, labels, focus states)
- CSS best practices (box-sizing, relative units)
- Responsive design patterns
- Any potential problems

Suggest specific improvements with code examples.

Let’s Build! 🚀

You now have the knowledge to:

  • Generate HTML/CSS with AI
  • Verify it’s semantic and accessible
  • Improve it for production quality
  • Test it properly in browsers