HTML Module 2 – Text, semantics and page structure
Emphasis, importance and inline semantics
Choose em, strong, i, b, u, s and mark by meaning, mark up titles, quotes and abbreviations, and add machine-readable dates with time and data.
What you will learn
- Choose em, strong, i, b, u, s and mark by meaning rather than appearance
- Use cite, q, abbr and dfn for titles of works, short quotations, abbreviations and definitions
- Add machine-readable dates, times and values with time and data, and validate datetime values
- Use code, kbd, samp, var, sub and sup for technical text, and ins, del and wbr for edits and long words
Before you start
What you’ll learn · Before you start
What you will learn
- Choose em, strong, i, b, u, s and mark by meaning rather than appearance
- Use cite, q, abbr and dfn for titles of works, short quotations, abbreviations and definitions
- Add machine-readable dates, times and values with time and data, and validate datetime values
- Use code, kbd, samp, var, sub and sup for technical text, and ins, del and wbr for edits and long words
Before you start
On this page
Inline elements say what a word or a phrase is doing inside a sentence. <em> changes where the stress falls,
<strong> marks something important, <i> sets off a term or a phrase in another language, <b> draws the eye
without adding importance, and <mark> highlights what is relevant right now. Others name things: the title of a
work (<cite>), a quotation (<q>), an abbreviation (<abbr>), a date (<time>) or a value (<data>), code
(<code>), keys to press (<kbd>) and a program’s output (<samp>).
Choose them by meaning, not by look. Browsers draw five of these elements in the same italic and two in the same bold, but they tell screen readers, search engines and translation tools different things. CSS can change how any of them looks; it cannot change what they mean.
Stress and importance: em and strong
<em> is stress emphasis: the word you would say louder or slower, and moving it changes the meaning of the
sentence. <strong> is strong importance, seriousness or urgency: a warning, or the part of a notice that people
must not miss. Both can be nested, and each level adds to it: the Standard says the level of stress is given by the
number of <em> ancestors, and the same holds for importance and <strong>.
<p>Take the <em>second</em> left after the temple, not the first.</p>
<p>Take the second left <em>after</em> the temple, not before it.</p>
<p>I asked for <em>one</em> cup of tea, not <em><em>three</em></em>.</p>
<p><strong>Never share your one-time password with anyone</strong>, even if the caller says they are from your bank.</p>
<p><strong>Warning:</strong> the bridge is closed for repairs. <strong><strong>Do not</strong> drive across it at night.</strong></p> The first two sentences use the same words, and only the stress tells the reader which left turn is meant. The
<strong> in the fourth sentence is a safety message, not a decoration.
The difference reaches assistive technology. HTML-AAM, which maps HTML to accessibility interfaces, gives <em> the
emphasis role and <strong> the strong role, and Chromium 153’s accessibility tree reported exactly those roles.
Screen readers can then report emphasis: NVDA, for example, has document formatting settings for emphasis and for
highlighted (marked) text.
Another voice, or attention: i and b
<i> is text in an alternate voice or mood: a technical term, a taxonomic name, a thought, the name of a ship, or a
phrase from another language. The Standard adds that terms in another language should carry a lang attribute, so
screen readers can pronounce them and browsers can pick suitable fonts. <b> draws attention without adding
importance or stress: keywords in a summary, a product name in a review, or the opening sentence of a news story. The
Standard calls <b> a last resort, for when no other element fits.
<p>The tree in our courtyard is a mango, <i>Mangifera indica</i>.</p>
<p>Fixing the leak with a rubber band was pure <i lang="hi-Latn">jugaad</i>: it held until the plumber came.</p>
<p><i>Did I lock the door?</i> she wondered, halfway to the station.</p>
<p><b>Heavy rain is expected across the city on Friday.</b> Schools will stay open, and buses will run as usual.</p>
<p>Spot the mistake: I will <u class="spelling-error">recieve</u> the parcel tomorrow.</p>
<p>Price: <s>₹1,999</s> ₹1,499 this week.</p>
<p>Results for "monsoon": the <mark>monsoon</mark> reached the coast early this year.</p>
<p><small>Prices include GST. Offer valid while stocks last.</small></p> Unlike <em> and <strong>, neither <i> nor <b> has a role of its own: both map to the generic role, so what
they mean stays in the markup, for your CSS and for tools that read the HTML, but screen readers get nothing extra.
That is fine for a mango’s Latin name. It is not fine for a warning, which needs <strong>.
Annotations, corrections, highlights and small print: u, s, mark and small
The rest of that example shows four more elements:
<u>is an annotation that is not spoken, such as marking a misspelt word. The Standard warns that underlining is how links are usually drawn, so avoid<u>where it could be taken for a link.<s>marks content that is no longer accurate or relevant, such as an old price. For a change to a document, such as a corrected time in a notice, use<del>and<ins>instead (they are further down).<mark>highlights text because it is relevant in the current context, for example the words someone searched for in a list of results.<small>is for side comments and small print, such as tax notes or legal lines. It does not lower the importance of anything: to make text unimportant, just leave it unmarked.
Chromium’s accessibility tree gave <s> the deletion role and <mark> the mark role, while <u> and <small>
stayed generic.
Titles, quotations, abbreviations and definitions
<p>Rabindranath Tagore's <cite>Gitanjali</cite> is a collection of poems.</p>
<p>The guide put it simply: <q>Water early, and feel the soil before you water again.</q></p>
<p>All prices include <abbr title="Goods and Services Tax">GST</abbr> (Goods and Services Tax).</p>
<p>A <dfn>void element</dfn> is an element that has no content and no end tag, such as <code>br</code>.</p> <cite>is the title of a work: a book, a song, a film, a law, a paper. The Standard is explicit that a person’s name is not the title of a work, so<cite>wraps Gitanjali, not “Rabindranath Tagore”.<q>is a short quotation inside a sentence, and the browser adds the quotation marks, so you must not type your own around it.<abbr>marks an abbreviation, and itstitleattribute can hold the expansion. Do not rely on that title alone: the Standard itself discourages relying ontitle, because many browsers show it only as a tooltip under a mouse pointer, which keyboard users and anyone on a phone never see. Spell the term out the first time, as the example does with “Goods and Services Tax”.<dfn>marks the place where a term is defined, which makes its paragraph the term’s definition. Chromium exposed it with thetermrole.
The quotation marks that <q> adds depend on the language of the text, set with lang. On a test page with the same
nested quotation in nine languages, Chromium 153 and Firefox 155 drew the same marks:
lang |
Outer and inner marks drawn |
|---|---|
en, en-GB, hi, mr, ta |
“outer ‘inner’ end” |
de |
„outer ‚inner‘ end“ |
fr |
«outer «inner» end» |
ja |
「outer 『inner』 end」 |
ur, in a left-to-right paragraph |
”outer ’inner‘ end“, which looks reversed |
The Urdu line looks wrong because Urdu is written right to left and the paragraph was left to right; the lesson on
languages and text direction shows how dir="rtl" fixes it.
Dates, times and values computers can read: time and data
People write dates and prices for people, in words and with commas, in the formats of their own country. Programs
need one exact form. <time> keeps the human text and adds a machine-readable datetime attribute; <data> does the same for any
other value with its value attribute.
<p>
The new phone goes on sale on
<time datetime="2026-11-20T12:00+05:30">20 November at noon (India time)</time>
for <data value="18999">₹18,999</data>.
</p>
<p>The launch stream lasts <time datetime="PT1H30M">an hour and a half</time>.</p>
<p>Store hours: <time datetime="10:00">10 am</time> to <time datetime="21:00">9 pm</time>.</p> Scripts read these through properties: in Chromium 153 and Firefox 155, the dateTime property of the first <time>
returned 2026-11-20T12:00+05:30, and the value property of the <data> returned 18999. The datetime value
must follow one of ten exact syntaxes in the Standard: a year, a month, a date, a date without a year, a time, a local
date and time, a global date and time with a time-zone offset, an offset alone, a week, or a duration. India’s offset
from UTC is written +05:30; a zone name such as IST is not allowed.
This program checks some strings people often write against those ten syntaxes, and explains the failures:
// Is this a valid datetime value for <time>? The HTML Standard accepts exactly ten syntaxes (a year, a month, a date,
// a date without a year, a time, a local or a global date and time, a time-zone offset, a week, a duration). This
// program checks strings that people often write against those rules, and says why the others fail.
const pad = "(\\d{2})";
const DATE = `(\\d{4,})-${pad}-${pad}`;
const TIME = `${pad}:${pad}(?::${pad}(?:\\.\\d{1,3})?)?`;
const ZONE = `(?:Z|[+-]${pad}:?${pad})`;
const isLeap = (y) => (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0;
const daysIn = (y, m) => [31, isLeap(y) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][m - 1];
const MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
function weeksIn(y) {
const jan1 = new Date(Date.UTC(y, 0, 1)).getUTCDay(); // 0 is Sunday, 4 is Thursday
return jan1 === 4 || (jan1 === 3 && isLeap(y)) ? 53 : 52;
}
const timeOk = (h, mi, s = "0") => Number(h) <= 23 && Number(mi) <= 59 && Number(s) <= 59;
const dateOk = (y, m, d) => Number(y) > 0 && Number(m) >= 1 && Number(m) <= 12 && Number(d) >= 1 && Number(d) <= daysIn(Number(y), Number(m));
function zoneOk(zone) {
if (zone === "Z") return true;
const [, h, m] = /^[+-](\d{2}):?(\d{2})$/.exec(zone);
if (Number(h) > 23 || Number(m) > 59) return false;
return !(zone.startsWith("-") && Number(h) === 0 && Number(m) === 0); // a zero offset is never negative
}
/** The syntax a string matches, or null. */
function kindOf(v) {
let m;
if (/^\d{4,}$/.test(v) && /[1-9]/.test(v)) return "a year";
if ((m = /^(\d{4,})-(\d{2})$/.exec(v)) && Number(m[1]) > 0 && Number(m[2]) >= 1 && Number(m[2]) <= 12) return "a month";
if ((m = new RegExp(`^${DATE}$`).exec(v)) && dateOk(m[1], m[2], m[3])) return "a date";
if ((m = /^(?:--)?(\d{2})-(\d{2})$/.exec(v)) && dateOk(2000, m[1], m[2])) return "a date without a year";
if ((m = new RegExp(`^${TIME}$`).exec(v)) && timeOk(m[1], m[2], m[3])) return "a time";
if ((m = new RegExp(`^${DATE}[T ]${TIME}$`).exec(v)) && dateOk(m[1], m[2], m[3]) && timeOk(m[4], m[5], m[6])) return "a local date and time";
if ((m = new RegExp(`^${DATE}[T ]${TIME}(${ZONE})$`).exec(v)) && dateOk(m[1], m[2], m[3]) && timeOk(m[4], m[5], m[6]) && zoneOk(m[7])) return "a global date and time";
if (new RegExp(`^${ZONE}$`).test(v) && zoneOk(v)) return "a time-zone offset";
if ((m = /^(\d{4,})-W(\d{2})$/.exec(v)) && Number(m[1]) > 0 && Number(m[2]) >= 1 && Number(m[2]) <= weeksIn(Number(m[1]))) return "a week";
if (/^P(?=\d|T\d)(?:\d+D)?(?:T(?=\d)(?:\d+H)?(?:\d+M)?(?:\d+(?:\.\d{1,3})?S)?)?$/.test(v)) return "a duration";
const parts = [...v.matchAll(/\s*(\d+(?:\.\d{1,3})?)\s*([WDHMS])\s*/gi)];
if (parts.length && parts.map((p) => p[0]).join("") === v) {
const scales = parts.map((p) => p[2].toUpperCase());
const fractionOnSeconds = parts.every((p) => !p[1].includes(".") || p[2].toUpperCase() === "S");
if (new Set(scales).size === scales.length && fractionOnSeconds) return "a duration";
}
return null;
}
/** Why a string matches none of the syntaxes (the common mistakes first). */
function whyNot(v) {
let m;
if (/^\d{1,2}[-/.]\d{1,2}[-/.]\d{4}$/.test(v)) return "the year comes first, with four digits, then the month and the day";
if (/[ap]\.?m\.?$/i.test(v)) return "there is no am or pm: write the time on the 24-hour clock";
if ((m = new RegExp(`^${DATE}$`).exec(v)) && Number(m[2]) >= 1 && Number(m[2]) <= 12) return `${MONTHS[Number(m[2]) - 1]} ${m[1]} has ${daysIn(Number(m[1]), Number(m[2]))} days`;
if (/[T ]\d{2}:\d{2}(:\d{2})?\s?[A-Z]{2,4}$/.test(v)) return "a time zone is an offset such as +05:30 or Z, not a name";
if (/-00:?00$/.test(v)) return "an offset of zero is written +00:00 or Z, never with a minus sign";
if ((m = new RegExp(`^${TIME}$`).exec(v)) && !timeOk(m[1], m[2], m[3])) return "hours go from 00 to 23, minutes and seconds from 00 to 59";
if ((m = /^(\d{4,})-W(\d{2})$/.exec(v))) return `${m[1]} has ${weeksIn(Number(m[1]))} weeks`;
if (/^P.*[YM](?![^T]*T)/.test(v) && !/^PT/.test(v)) return "a duration cannot hold years or months, whose length varies";
if (/^PT?\d+\.\d+[DHM]/.test(v)) return "only the seconds of a duration may have a fraction";
return "it matches none of the ten syntaxes";
}
const CANDIDATES = [
"2026-11-20", "2026-11-20T12:00+05:30", "2026-11-20 12:00", "2026-11", "2026", "11-20", "12:00", "+05:30",
"2026-W53", "PT1H30M", "1h 30m", "20-11-2026", "12:00 PM", "2026-11-31", "2026-02-29", "2026-11-20T12:00 IST",
"2026-11-20T12:00-00:00", "24:00", "2027-W53", "P1M", "PT1.5H",
];
for (const v of CANDIDATES) {
const kind = kindOf(v);
console.log(`${JSON.stringify(v).padEnd(26)} ${kind ? `valid: ${kind}` : `not valid: ${whyNot(v)}`}`);
} Output
"2026-11-20" valid: a date "2026-11-20T12:00+05:30" valid: a global date and time "2026-11-20 12:00" valid: a local date and time "2026-11" valid: a month "2026" valid: a year "11-20" valid: a date without a year "12:00" valid: a time "+05:30" valid: a time-zone offset "2026-W53" valid: a week "PT1H30M" valid: a duration "1h 30m" valid: a duration "20-11-2026" not valid: the year comes first, with four digits, then the month and the day "12:00 PM" not valid: there is no am or pm: write the time on the 24-hour clock "2026-11-31" not valid: November 2026 has 30 days "2026-02-29" not valid: February 2026 has 28 days "2026-11-20T12:00 IST" not valid: a time zone is an offset such as +05:30 or Z, not a name "2026-11-20T12:00-00:00" not valid: an offset of zero is written +00:00 or Z, never with a minus sign "24:00" not valid: hours go from 00 to 23, minutes and seconds from 00 to 59 "2027-W53" not valid: 2027 has 52 weeks "P1M" not valid: a duration cannot hold years or months, whose length varies "PT1.5H" not valid: only the seconds of a duration may have a fraction
Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node datetime-check.mjs
The Nu Html Checker, given the same 21 strings in <time datetime> attributes, rejected nine of the ten that the
program rejects, with messages such as Day out of range. and
Minus sign not allowed in time zone designator when offset is zero. Use plus sign instead. It accepted the tenth, 2027-W53: by the Standard’s week rule, a year has 53 weeks only when it
starts on a Thursday (or on a Wednesday in a leap year), and 2027 starts on a Friday.
Validators can miss edge cases, so test the values your code generates. html-validate 11.16.1 does not check
datetime values at all.
Code, keys, output and variables
<p>To save the file, press <kbd><kbd>Ctrl</kbd>+<kbd>S</kbd></kbd>, or <kbd><kbd>Cmd</kbd>+<kbd>S</kbd></kbd> on a Mac.</p>
<p>The <code>lang</code> attribute goes on the <code><html></code> element.</p>
<p>If the build stops with <samp>Error: file not found</samp>, check the path.</p>
<p>The area of a rectangle is <var>w</var> × <var>h</var>.</p>
<p>Water is H<sub>2</sub>O, and a square of side 10 cm has an area of 10<sup>2</sup> cm<sup>2</sup>.</p> <code>is a fragment of computer code: an element name, a property, a file name.<kbd>is input the user gives, usually keys. Inside another<kbd>, it is one key, so a shortcut is a<kbd>holding one<kbd>per key.<samp>is output from a program, such as an error message.<var>is a variable, in maths or in code.<sub>and<sup>are for subscripts and superscripts that carry meaning, as in H₂O or 10². The Standard says to use them only where leaving them out would change the meaning, never just for looks.
Both engines drew <code>, <kbd> and <samp> in a monospace font at 13px, smaller than the 16px text around them.
Code samples longer than a line belong in <pre>, which the next lesson covers, together with how to show < and
& in code.
Edits and line-break opportunities: ins, del and wbr
<ins> and <del> record changes to a document. Both accept a datetime with the time of the change and a cite
with the address of a page that explains it. Chromium exposed them with the insertion and deletion roles.
<p>
The workshop starts at
<del datetime="2026-11-02T09:00+05:30">10 am</del>
<ins datetime="2026-11-02T09:00+05:30">11 am</ins>
in Hall B.
</p>
<p>Read the full rules at https://example.org/<wbr>community-library/<wbr>membership-rules-and-fees</p> <wbr> marks a place where a long word or address may break onto the next line, if it does not fit. Without it, a long
web address in narrow text can stick out of its box on a phone.
How the browser draws them by default
These are the default styles that Chromium 153 and Firefox 155 computed for each element on a page with no CSS of its own, next to the role Chromium gave it:
| Default look | Element (role in Chromium 153) |
|---|---|
| Italic | em (emphasis), i (generic), cite (generic), dfn (term), var (generic) |
| Bold (weight 700) | strong (strong), b (generic) |
| Underlined | u (generic), ins (insertion); abbr with a title: dotted underline |
| Struck through | s (deletion), del (deletion) |
Yellow background, rgb(255, 255, 0) |
mark (mark) |
| Monospace, 13px | code (code), kbd (generic), samp (generic) |
| Smaller (13.33px) and raised or lowered | sup (superscript), sub (subscript) |
| Smaller (13.33px) | small (generic) |
| No change | q (quotation marks added), time (time), data (generic) |
The table is the reason to choose by meaning. If you pick <i> because you want italics, the page looks right and
says nothing more; if you pick <em>, it also says where the stress is. And when a designer later wants emphasis in
bold, one CSS rule changes every <em> without touching the meaning.
Try it: mark up a notice
Mark up this library notice with inline elements:
- “The library will not open on Monday” must be stressed as a correction of what people expect, and the whole sentence is important.
- The reopening time, Tuesday at 10 am, needs a machine-readable form: a global date and time with India’s offset (pick the date of any Tuesday).
- The late fee, 50 rupees a day, needs a machine-readable number.
- “OPAC” is the library’s search system, the Online Public Access Catalogue: mark it as an abbreviation and spell it out the first time.
- The old opening time, 9 am, is no longer accurate and should stay visible but struck through, next to the new one.
- The book title Gitanjali appears in the sentence “Return Gitanjali before you borrow another book.”
Then check your datetime value with the Nu Html Checker or the site’s HTML Validator. One answer:
<h2>Library notice</h2>
<p><strong>The library will <em>not</em> open on Monday.</strong></p>
<p>
It reopens on <time datetime="2026-11-24T10:00+05:30">Tuesday at 10 am</time>.
New opening time: <s>9 am</s> 10 am.
</p>
<p>Late returns cost <data value="50">₹50</data> a day.</p>
<p>
Search the <abbr title="Online Public Access Catalogue">OPAC</abbr> (Online Public Access Catalogue)
to see which books are in.
</p>
<p>Return <cite>Gitanjali</cite> before you borrow another book.</p> Check yourself
6 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.
Interview questions
What is the difference between <em> and <strong>?
<em> marks stress emphasis: the word you would stress when reading the sentence aloud, and moving it changes the
meaning (“take the second left” against “take the second left after the temple”). <strong> marks importance,
seriousness or urgency, such as a warning that people must not miss, without changing how the sentence is read. Both
can be nested to add more stress or more importance. Browsers draw <em> in italic and <strong> in bold by default,
but that is only a default. HTML-AAM maps them to the emphasis and strong roles, and screen readers such as NVDA
can be set to report them. If you only want italic or bold text with no extra meaning, <i>, <b> or CSS is the
better choice.
Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.
-
Fresher to mid
A rich-text editor saves every press of its Bold and Italic buttons as b and i. An accessibility review asks for semantic markup instead. What do you change, and why can't you simply replace every b with strong and every i with em?
-
Mid to senior
Event pages show "6:30 pm IST, Saturday" to visitors worldwide, and the calendar export and search snippets sometimes show the wrong hour. How do you mark up the event time so programs read it correctly, and what goes wrong with a datetime value of 18:30 alone?
Key takeaways
- Choose inline elements by meaning:
emstress,strongimportance,ianother voice or language,battention,markrelevance,sno longer accurate,smallside comments. - Five elements look italic and two look bold by default, but only some carry a role:
emisemphasisandstrongisstrong, whileiandbaregeneric. citeis a title, never a person;qadds language-specific quotation marks itself; spell out abbreviations on first use rather than relying ontitle.time datetimeanddata valueadd exact values;datetimemust follow one of the Standard’s ten syntaxes, with offsets such as+05:30.code,kbd,sampandvarmark technical text; usesubandsuponly when they carry meaning;insanddelrecord edits, andwbrlets long words break.
References
- HTML Standard: Text-level semantics (WHATWG)
- HTML Standard: Edits (ins and del) (WHATWG)
- HTML Standard: Dates and times (common microsyntaxes) (WHATWG)
- HTML Standard: the title attribute (WHATWG)
- HTML Accessibility API Mappings (HTML-AAM) (W3C)
- NVDA User Guide (document formatting settings) (NV Access)
- The Nu Html Checker (The Nu Html Checker project)
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress