---
title: 'Meta Tags'
source: 'https://academia.sh/en/courses/web-fundamentals-and-html/meta-tags'
course: 'Web Fundamentals and HTML'
language: en
updated: '2026-08-17T18:09:31+00:00'
license: 'CC BY-SA 4.0'
---

# Meta Tags

How the charset declaration decides byte interpretation, the priority of sources that determine encoding, the viewport declaration, and named metadata.

The previous lesson made an assumption while resolving character references: which rule bytes
were turned into characters by was already known. This lesson lifts that assumption and takes
up the metadata tags in the head section, starting with the most decisive one.

The `meta` element is a void element and carries no meaning on its own; what carries meaning
is its attributes. It is used in four separate functions, and these are independent of one
another.

## The Charset Declaration

The Character Encodings lesson in the How Computers Work course established a single point: a
byte sequence does not say, on its own, which rule it was written with. The same bytes resolve
to different characters under different rules.

```js
// charset.mjs — same bytes, two separate encoding assumptions
// The measured text is kept in Turkish on purpose: the lesson measures the exact
// byte pattern (c4 b1) of the letter "ı", which has no equivalent in English.
const text = "Sıcaklık: -4 °C";
const bytes = Buffer.from(text, "utf8");

const codePoints = (d) =>
  [...d].map((k) => "U+" + k.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")).join(" ");

console.log("bytes           :", bytes.toString("hex").match(/../g).join(" "));
console.log("byte count      :", bytes.length);
console.log("char count      :", text.length);
console.log("utf-8 reading   :", bytes.toString("utf8"));
console.log("latin1 reading  :", bytes.toString("latin1"));
console.log("utf-8 first 3   :", codePoints(bytes.toString("utf8").slice(0, 3)));
console.log("latin1 first 5  :", codePoints(bytes.toString("latin1").slice(0, 5)));

console.log("--- the charset declaration is searched for in the document's first bytes ---");
const head = '<!doctype html>\n<html lang="en">\n<head>\n<meta charset="utf-8">\n';
console.log("byte declaration ends at:", Buffer.byteLength(head));
console.log("under 1024 bytes        :", Buffer.byteLength(head) < 1024);
```

```
bytes           : 53 c4 b1 63 61 6b 6c c4 b1 6b 3a 20 2d 34 20 c2 b0 43
byte count      : 18
char count      : 15
utf-8 reading   : Sıcaklık: -4 °C
latin1 reading  : SÄ±caklÄ±k: -4 Â°C
utf-8 first 3   : U+0053 U+0131 U+0063
latin1 first 5  : U+0053 U+00C4 U+00B1 U+0063 U+0061
--- the charset declaration is searched for in the document's first bytes ---
byte declaration ends at: 63
under 1024 bytes        : true
```

The byte pair `c4 b1` resolves to a single character under one rule (U+0131, `ı`); under
another rule, to two separate characters (U+00C4 and U+00B1). The bytes are the same; only
the interpretation differs. Eighteen bytes give fifteen characters under the first reading,
eighteen under the second.

The document's own declaration is a single line:

```html
<meta charset="utf-8">
```

This line's effect is not visual, it is structural. If the declaration is wrong, it is not
just a few characters that break; the document resolves into an entirely different character
sequence, and even tag names can be affected.

## Why the Declaration's Place Matters

There is a circular problem here. The declaration itself is inside the document; reading it
requires decoding the document, and decoding requires reading the declaration.

The solution is a pre-scan. The parser scans the document's first section — the defined limit
is 1024 bytes — with a single-byte assumption and looks only for a `charset` declaration. If
it finds one, it starts parsing the document with that rule.

This has two consequences. First, the declaration has to be within the first 1024 bytes; this
is why it is written at the very start of the head section. Second, if the declaration falls
outside this limit or is not found during the pre-scan with the default rule, the parser has
already started with the wrong rule; once it sees the declaration later, it has to redo
parsing **from the start.** This restart is a measurable cost, and it is avoided by the
declaration's placement.

## Sources That Determine Encoding

The `meta` declaration in the document is not the only source. There is an ordered priority
list.

| Priority | Source |
|---|---|
| 1 | Byte order mark (BOM) |
| 2 | The user's explicit choice |
| 3 | Transport layer: the `charset` in the HTTP `Content-Type` header |
| 4 | The `meta charset` declaration in the document |
| 5 | Sniffing and default |

The byte order mark concept was defined in the Byte Order lesson of the How Computers Work
course; a few bytes at the start of the document state the encoding and override everything
else.

The third rank deserves attention: **the HTTP header overrides the document's declaration.**
The HTTP Request and Response lesson in the How the Internet Works course showed that the
`Content-Type` header carries a `charset` parameter. That parameter applies even if the
document carries a different declaration. If the server configuration and the document
conflict, the server wins; this is a frequent reason why characters that look broken are
searched for in the document and not found.

The fifth rank is not a guarantee. Sniffing makes a guess by looking at the document's content,
and the guess can be wrong. Not writing the declaration means leaving the result to the
environment.

## The Viewport Declaration

The second use of `meta` declares how the document will scale on narrow screens.

```html
<meta name="viewport" content="width=device-width, initial-scale=1">
```

This declaration's reason is historical. Narrow-screen devices assume a wide virtual viewport
to keep documents not written for a narrow screen readable, and shrink the page. The
declaration turns off this assumption: the viewport's width is taken as the device's own
width, and the initial scale is one.

The declaration itself is not a presentation decision; it decides which width the presentation
layer will compute against. For this reason it is present in every document that accounts for
narrow screens, and it is the precondition for the responsive layout covered in the next
course.

Values that turn off scaling, like `user-scalable=no`, can be written. They should not be:
zooming in is the only access path for users with limited vision, and turning it off is an
accessibility violation.

## Named Metadata

The third use declares information about the document with a `name`/`content` pair. This
information is not painted; it is carried for programs that process the document.

```html
<meta name="description" content="Temperature, relative humidity, wind speed,
      and precipitation records from the North Slope automated measurement station.">
<meta name="robots" content="index, follow">
<meta name="author" content="Measurement Network Working Group">
```

The `description` value can be used as the document's summary shown in search results. It is
not guaranteed to be used — indexers can choose to produce a more suitable summary from the
document's content. Writing it is still justified: when it is not written, the choice is left
entirely to the indexer.

The `robots` value tells indexers whether the document should be indexed and whether its links
should be followed. This is not an access control; a client that does not follow the
declaration still reads the document. Content requiring privacy is protected with
authorization, not with metadata.

There are separate metadata contracts for systems that preview the document in other
environments; these use the same `meta` mechanism and declare fields like title, description,
and image address. Contract names vary from platform to platform; what is common is that the
preview is explicitly declared instead of being guessed from the document's content.

## Equivalent Headers

The fourth use declares the equivalent of an HTTP response header with the `http-equiv`
attribute.

```html
<meta http-equiv="content-security-policy" content="default-src 'self'">
```

This mechanism is for situations where there is no way to change the server's headers. If
there is a way, the real header is preferred: the header applies before the document is
parsed, the `http-equiv` declaration only once the parser reaches it. This difference is
decisive for security declarations.

## The Station Document's Head Section

The head section of the document developed throughout the course becomes this:

```html
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>North Slope Measurement Station — Measurement Network</title>
  <meta name="description" content="Temperature, relative humidity, wind speed,
        and precipitation records from the North Slope automated measurement station.">
</head>
```

The order is not incidental: the encoding declaration comes first, because it decides how
everything after it will be read. The `title` element, as noted in the previous lesson, names
the document outside its context, and here it also carries the site's name.

## Summary

- The charset declaration says which rule bytes will be converted to characters by; a wrong
  declaration resolves the whole document into a different character sequence.
- Because of the parser's pre-scan, the declaration has to be within the first 1024 bytes;
  being found late means parsing has to be redone from the start.
- Sources that determine encoding have a priority, and the HTTP header overrides the
  document's declaration.
- The viewport declaration decides which width the presentation layer computes against; values
  that turn off scaling break accessibility.
- Named metadata is for programs that process the document and is not binding; indexing
  declarations provide no access control.
- `http-equiv` declarations stand in for real HTTP headers but apply later; the header is
  preferred where possible.

## Next Step

The head section is complete; next comes the body. The body's first structural decision is
headings: the tags that declare which sections the document is divided into and these
sections' level relative to one another. The next lesson shows why heading level is a
structural declaration rather than a font size, and how skipping a level breaks the
document's outline.
