HTML for the Artful Microbiologist
A modern beginner tutorial for someone who likes visual structure, careful labels, living systems, and web pages that make sense before they are decorated.
HTML is not the boring part of frontend development. It is the specimen label, the slide tray, the field notebook, the gallery wall, and the lab map. Good HTML tells browsers, search engines, screen readers, future teammates, and your own future self what each piece of content means.
CSS can make a page beautiful. JavaScript can make a page respond and remember. But HTML gives the page a body.
The goal is not to memorize every element.
The goal is to choose meaningful elements most of the time, reach for native browser behavior before inventing your own, and build pages that are easy to style and easy to understand.
0. The Gentle Rule
HTML answers one main question:
What is this thing?
A heading is a heading. A paragraph is a paragraph. A navigation menu is navigation. A form control needs a label. A table is for real tabular data. A button performs an action. A link goes somewhere.
That sounds simple because it is simple. The difficulty is that beginners often ask the wrong first question:
How do I make this look right?
That is a CSS question. In HTML, ask what the content is before asking how it should look.
Think of preparing a microscope slide. You do not start with the stain. First you identify the specimen, label it, place it correctly, and record the context. Then the stain reveals what is already there.
HTML is the careful preparation.
1. Elements, Tags, and Attributes
An HTML element is usually made of an opening tag, content, and a closing tag.
<p>A violet stain reveals the cell wall pattern.</p>
Some elements also have attributes. Attributes add useful information.
<a href="https://developer.mozilla.org/">Read MDN Web Docs</a>
Here, a means anchor, which creates a link. href says where the link goes.
Many attributes are global, which means many elements can use them. Common examples are id, class, title, hidden, and data-*.
<article id="sample-a17" class="sample-card" data-stain="gram-positive">
<h2>Sample A17</h2>
<p>Round colonies with soft lavender edges.</p>
</article>
Use class mostly for styling. Use id when something needs a unique name, such as a form label pointing to one input or a button pointing to one popover.
Use data-* when you want to attach quiet custom information that JavaScript or CSS may use later.
2. The Page Skeleton
A modern HTML page starts with a small amount of structure.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Culture Sketchbook</title>
<meta
name="description"
content="A small notebook of microbiology observations and sketches."
>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main>
<h1>Culture Sketchbook</h1>
<p>Observe carefully. Label clearly. Style later.</p>
</main>
</body>
</html>
The doctype tells the browser to use modern HTML behavior. The lang attribute helps assistive technology and translation tools. The head contains page information. The body contains what people see and use.
The viewport line helps the page size itself properly on phones. The stylesheet link connects CSS to the page.
That is the basic lab bench.
3. Semantic HTML Means Meaningful HTML
Semantic HTML uses elements that describe meaning, not appearance.
These elements are semantic:
headerfor introductory contentnavfor navigationmainfor the unique main content of the pagesectionfor a themed regionarticlefor a self-contained itemasidefor related side contentfooterfor closing informationfigureandfigcaptionfor media with a captionform,label, andinputfor collecting information
These elements are generic:
divfor a block with no special meaningspanfor inline text with no special meaning
Generic elements are not bad. They are like blank containers. Use them when no more meaningful element fits.
A good semantic page reads almost like an outline.
<header>
<p>Culture Notebook</p>
<nav aria-label="Main navigation">
<ul>
<li><a href="/samples/">Samples</a></li>
<li><a href="/sketches/">Sketches</a></li>
<li><a href="/notes/">Notes</a></li>
</ul>
</nav>
</header>
<main>
<article>
<header>
<h1>Penicillium Study</h1>
<p>Observed on 12 July after five days of growth.</p>
</header>
<section aria-labelledby="appearance-heading">
<h2 id="appearance-heading">Appearance</h2>
<p>Soft green center with a pale rim and powdery surface.</p>
</section>
</article>
</main>
<footer>
<p>Notebook maintained by the lab art club.</p>
</footer>
Notice that CSS has not entered yet. We are not saying whether the header is purple, centered, large, or decorative. HTML only says what each piece is.
4. Headings Are the Page Outline
Headings are not chosen by size. They are chosen by structure.
h1 is the main heading of the page or article. h2 is a major section. h3 is a subsection inside an h2, and so on.
<main>
<h1>Water Sample Report</h1>
<section>
<h2>Collection Details</h2>
<p>Collected from the east pond at 7:30 AM.</p>
</section>
<section>
<h2>Microscope Observations</h2>
<section>
<h3>Motility</h3>
<p>Several organisms moved in short darting patterns.</p>
</section>
</section>
</main>
Do not skip from h1 to h4 just because the browser's default h4 looks smaller. That is using HTML as decoration. Use CSS to change size.
A useful test: if someone read only the headings, would the page make sense?
5. Text Content: The Quiet Workhorses
Most pages are made from humble elements.
<p>Good observation is slow attention.</p>
<ul>
<li>Color</li>
<li>Texture</li>
<li>Shape</li>
</ul>
<ol>
<li>Label the plate.</li>
<li>Record the medium.</li>
<li>Sketch the colony edges.</li>
</ol>
<blockquote>
<p>There is art in noticing what changed.</p>
</blockquote>
Use unordered lists when order does not matter. Use ordered lists when sequence matters.
Use blockquote for quoted material. Use p for normal paragraphs. Avoid using line breaks to create fake paragraphs. Let paragraphs be paragraphs.
For tiny pieces of text that need emphasis, use meaningful inline elements.
<p>
The colony was <strong>rapidly spreading</strong>, but the edge remained
<em>feathery</em> rather than sharp.
</p>
strong means importance. em means emphasis. They have default visual styles, but their real job is meaning.
6. Links and Buttons Are Different
A link goes somewhere.
<a href="/samples/a17/">Open Sample A17</a>
A button does something on the current page.
<button type="button">Add observation</button>
This distinction matters. A link is for navigation. A button is for action.
Do not use a link when you mean button only because it is easier to style. CSS can style either one.
<a class="button-link" href="/new-sample/">Create a new sample</a>
<button class="soft-button" type="button">
Shuffle stain palette
</button>
The first one navigates to another page, so it is a link. The second one changes something on the current page, so it is a button.
When a button is inside a form, give it an explicit type. This prevents accidental form submission.
<button type="submit">Save sample</button>
<button type="button">Preview card</button>
7. Images, Alt Text, and Figures
Images need text alternatives.
<img
src="colony-a17.jpg"
alt="Round cream colonies with violet shadows at the edges"
>
Good alt text describes the useful content of the image. It does not need to begin with "image of" because the browser already knows it is an image.
If an image is purely decorative, use an empty alt attribute.
<img src="paint-splash.svg" alt="">
When an image has a visible caption, wrap it in figure.
<figure>
<img
src="penicillium-sketch.jpg"
alt="Watercolor sketch of a green Penicillium colony"
>
<figcaption>
Penicillium sketch, painted after the third observation day.
</figcaption>
</figure>
figure says, "this media and this caption belong together." That is richer than a random image followed by a paragraph.
8. Sections, Articles, Divs, and Spans
Use article when the piece could stand alone.
A blog post, a sample card, a recipe, a lab note, and a gallery entry can often be articles.
<article class="sample-card">
<h2>Sample A17</h2>
<p>Cream colonies with violet shadows.</p>
</article>
Use section for a themed region that usually deserves a heading.
<section aria-labelledby="materials-heading">
<h2 id="materials-heading">Materials</h2>
<ul>
<li>Agar plate</li>
<li>Inoculating loop</li>
<li>Labeling tape</li>
</ul>
</section>
Use div when you need a block for layout or styling but no semantic element fits.
<div class="card-grid">
<article class="sample-card">...</article>
<article class="sample-card">...</article>
</div>
Use span when you need to target a small inline piece.
<p>
Status:
<span class="status-pill">incubating</span>
</p>
A div is not a mistake. A page made almost entirely of divs is usually a missed opportunity.
9. Forms: Labels Before Decoration
Forms are where many beginner pages become messy. The antidote is simple: every input should have a clear label.
<form action="/samples" method="post">
<label for="sample-code">Sample code</label>
<input id="sample-code" name="sampleCode" required>
<label for="medium">Growth medium</label>
<select id="medium" name="medium" required>
<option value="">Choose one</option>
<option value="nutrient-agar">Nutrient agar</option>
<option value="sabouraud">Sabouraud agar</option>
<option value="blood-agar">Blood agar</option>
</select>
<button type="submit">Save sample</button>
</form>
The for attribute on the label matches the input's id. This gives the input a name that assistive technology can announce, and it lets the user click the label to focus the input.
HTML also gives you useful validation without JavaScript.
<label for="colonies">Colony count</label>
<input
id="colonies"
name="colonies"
type="number"
min="0"
max="5000"
step="1"
required
>
A longer note can use textarea.
<label for="note">Observation note</label>
<textarea
id="note"
name="note"
maxlength="220"
placeholder="Cream colonies, violet shadows, soft edges..."
required
></textarea>
Group related controls with fieldset and legend.
<fieldset>
<legend>Stain result</legend>
<label>
<input type="radio" name="stain" value="gram-positive" required>
Gram-positive
</label>
<label>
<input type="radio" name="stain" value="gram-negative">
Gram-negative
</label>
<label>
<input type="radio" name="stain" value="unclear">
Unclear
</label>
</fieldset>
A form is not only a visual design. It is a conversation between the page and the user. Labels are the page speaking clearly.
10. Details and Summary: Native Accordions
Do not use JavaScript for a simple expandable note. HTML already has details and summary.
<details>
<summary>Why did the colony edge look fuzzy?</summary>
<p>
Fuzzy edges can suggest filamentous growth, spreading growth, or simply
a drawing that needs a softer brush. Observe again before deciding.
</p>
</details>
The browser gives this element open-and-close behavior. It works with keyboard interaction. CSS can style it.
JavaScript earns its place only when the open state must be saved, synchronized, measured, or connected to other data.
11. Popovers Without JavaScript
Modern HTML can open a small floating layer using popover and popovertarget.
<button type="button" popovertarget="gram-help">
What does Gram-positive mean?
</button>
<div id="gram-help" popover>
<p>
Gram-positive bacteria hold crystal violet stain because of their thick
peptidoglycan layer.
</p>
</div>
This is useful for small notes, definitions, action menus, and hints.
Use a popover for lightweight floating content. Use a full page section for important content that should always be visible. Use JavaScript when the popover content is generated from data or when opening it must trigger app logic.
12. Tables Are for Real Data
Tables are not for page layout. CSS grid and flexbox handle layout.
Use a table when the information truly belongs in rows and columns.
<table>
<caption>Incubation observations</caption>
<thead>
<tr>
<th scope="col">Day</th>
<th scope="col">Color</th>
<th scope="col">Texture</th>
<th scope="col">Diameter</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Cream</td>
<td>Smooth</td>
<td>2 mm</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Green center</td>
<td>Powdery</td>
<td>7 mm</td>
</tr>
</tbody>
</table>
caption gives the table a title. th marks header cells. scope clarifies whether a header describes a row or a column.
This is boring in the best possible way. Data deserves clarity.
13. Templates and Data Attributes
HTML can hold invisible templates that JavaScript may use later.
<template id="sample-card-template">
<article class="sample-card">
<h2></h2>
<p></p>
<button type="button">Remove</button>
</article>
</template>
The browser does not display template content by itself. It is like an empty mold waiting for JavaScript to clone it.
Data attributes are another gentle bridge from HTML to CSS or JavaScript.
<article class="sample-card" data-mood="calm" data-risk="low">
<h2>Blue-green wash</h2>
<p>A soft colony study with quiet edges.</p>
</article>
CSS can style this card based on data-mood. JavaScript can read the same information later.
HTML, CSS, and JavaScript work best when they share clean labels.
14. Accessibility Is Not an Extra Layer
Accessible HTML usually begins with ordinary good HTML.
Use the right element before adding ARIA. A real button is better than a div pretending to be a button. A real label is better than a placeholder pretending to be a label. A real heading is better than large bold text pretending to be a heading.
A few practical habits:
- give the page a clear
title - set the document language with
lang - use one clear
mainlandmark - write headings in order
- label every form control
- use meaningful link text
- write useful alt text for informative images
- use empty alt text for decorative images
- make buttons buttons and links links
ARIA can be useful, but it should not be the first paintbrush you reach for. Native HTML already carries a lot of meaning.
15. Mini Project: Culture Sketchbook Page
This project uses HTML only. It gives CSS and JavaScript a clean foundation later, but it already has structure, labels, validation, a table, a figure, an expandable note, and a popover.
Create a file named index.html.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Culture Sketchbook</title>
<meta
name="description"
content="A small semantic HTML page for microbiology observations."
>
</head>
<body>
<header>
<p>Culture Sketchbook</p>
<nav aria-label="Main navigation">
<ul>
<li><a href="#new-entry">New entry</a></li>
<li><a href="#gallery">Gallery</a></li>
<li><a href="#observations">Observations</a></li>
</ul>
</nav>
</header>
<main>
<section aria-labelledby="intro-heading">
<h1 id="intro-heading">A notebook for living patterns</h1>
<p>
Record the sample, sketch the mood, and let the page stay clear
before it becomes decorative.
</p>
<button type="button" popovertarget="label-help">
How should I label a sample?
</button>
<div id="label-help" popover>
<p>
Use a short code, the date, the medium, and one memorable visual
clue. Future-you is also a person who deserves kindness.
</p>
</div>
</section>
<section id="new-entry" aria-labelledby="form-heading">
<h2 id="form-heading">New sample entry</h2>
<form action="/samples" method="post">
<label for="sample-code">Sample code</label>
<input id="sample-code" name="sampleCode" required>
<label for="medium">Growth medium</label>
<select id="medium" name="medium" required>
<option value="">Choose one</option>
<option value="nutrient-agar">Nutrient agar</option>
<option value="sabouraud">Sabouraud agar</option>
<option value="blood-agar">Blood agar</option>
</select>
<label for="colonies">Colony count</label>
<input
id="colonies"
name="colonies"
type="number"
min="0"
max="5000"
step="1"
required
>
<fieldset>
<legend>Visual mood</legend>
<label>
<input type="radio" name="mood" value="calm" required>
Calm
</label>
<label>
<input type="radio" name="mood" value="strange">
Strange
</label>
<label>
<input type="radio" name="mood" value="dramatic">
Dramatic
</label>
</fieldset>
<label for="note">Observation note</label>
<textarea
id="note"
name="note"
maxlength="220"
placeholder="Cream colonies, violet shadows, soft edges..."
required
></textarea>
<button type="submit">Save entry</button>
</form>
</section>
<section id="gallery" aria-labelledby="gallery-heading">
<h2 id="gallery-heading">Sketch gallery</h2>
<article class="sample-card" data-mood="calm">
<figure>
<img
src="sample-a17.jpg"
alt="Watercolor sketch of round cream colonies"
>
<figcaption>Sample A17, cream colonies with violet shadows.</figcaption>
</figure>
<details>
<summary>Observation note</summary>
<p>
The colony edge looked soft rather than sharp. Recheck after the
next incubation period.
</p>
</details>
</article>
</section>
<section id="observations" aria-labelledby="table-heading">
<h2 id="table-heading">Observation log</h2>
<table>
<caption>Sample A17 growth notes</caption>
<thead>
<tr>
<th scope="col">Day</th>
<th scope="col">Color</th>
<th scope="col">Texture</th>
<th scope="col">Diameter</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Cream</td>
<td>Smooth</td>
<td>2 mm</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Green center</td>
<td>Powdery</td>
<td>7 mm</td>
</tr>
</tbody>
</table>
</section>
</main>
<footer>
<p>Made with semantic HTML, patient observation, and a little curiosity.</p>
</footer>
</body>
</html>
This page will look plain until CSS arrives. That is fine. The point is that the structure is already strong.
A beautiful building still needs a frame.
16. HTML Checklist
Before styling or scripting a page, ask:
- Does the page have one clear
h1? - Are headings in a sensible order?
- Is the main content inside
main? - Are navigation links inside
nav? - Are standalone cards or posts using
article? - Are themed regions using
sectionwith headings? - Does every input have a label?
- Are buttons used for actions and links used for navigation?
- Do informative images have useful alt text?
- Are decorative images given empty alt text?
- Are tables used only for real rows and columns?
- Can
details,summary, orpopoversolve this before JavaScript?
Good HTML feels like kindness. It gives every piece of content a name and a place.