Tag, Element, Content — Three Words People Mix Up
A tag is the thing in angle brackets: <p> is an opening tag, </p> is a closing tag. An element is the whole package — the opening tag, the content inside, and the closing tag together. So <p>Admissions open</p> is one paragraph element made of two tags and three words of content.
The distinction matters the moment you start using CSS or JavaScript, because both of them work on elements, not on tags. When a tutorial says "select the paragraph element and give it a margin", it means the whole thing, content included. When an error message says "unexpected closing tag", it means one specific tag in your file, and only that.
An element can also carry attributes — extra settings written inside the opening tag only, never in the closing tag. <a href="about.html">About</a> has one attribute called href whose value is about.html. Attributes get a full lesson later; for now, just note that they always go in the opening tag and are written as name="value".
<!-- Anatomy of an element -->
<p>Admissions open</p>
<!--
<p> opening tag
Admissions open content
</p> closing tag
the three together = one <p> element
-->
<!-- An element with an attribute -->
<a href="about.html">About the club</a>
<!-- ^^^^ attribute name ^^^^^ attribute value --> - Tag — one item in angle brackets, opening or closing
- Element — opening tag + content + closing tag, treated as a single thing
- Attribute — a setting written inside the opening tag as
name="value" - Content — the text or the other elements sitting between the two tags
Void Elements Have No Closing Tag
A handful of elements have nothing to wrap, because they are not containers — they insert something and then they are finished. These are called void elements, and they are written as a single tag with no closing partner. An image is a good example: the picture is specified entirely by the src attribute, so there is no content for a closing tag to enclose.
The list of void elements is short and worth memorising, because it is closed — you cannot invent new ones. The ones you will actually use are <img>, <br>, <hr>, <input>, <meta> and <link>. Writing </img> or </br> is simply an error; browsers ignore it, but validators will flag it and it makes your file look careless.
You will also see these written with a trailing slash, like <br />. That style comes from XHTML, an older stricter variant of HTML. In HTML5 the slash is allowed but does absolutely nothing — <br> and <br /> are identical to the browser. Pick whichever style your project uses and be consistent. What you must never do is add the slash to a normal element and assume it closes it: <div /> does not close a div, and everything after it ends up inside that div.
<!-- Correct: void elements, no closing tag -->
<img src="team.jpg" alt="The robotics team with their line-following robot">
<br>
<hr>
<input type="text" name="rollnumber">
<!-- Wrong: these closing tags are errors -->
<img src="team.jpg" alt="..."></img>
<br></br>
<!-- Dangerous: a slash does NOT close a normal element -->
<div class="card" />
<p>This paragraph is now trapped inside the div above.</p> - The complete list of void elements in HTML5 is
area,base,br,col,embed,hr,img,input,link,meta,source,trackandwbr. Every other element needs a closing tag.
Nesting: Last Opened, First Closed
Elements go inside other elements constantly — that is how you build a page. The one rule is that they must nest cleanly, like boxes inside boxes: whichever element you opened most recently is the one you must close first. Overlapping them, so that one element starts inside another and finishes outside it, describes a shape a tree cannot hold.
Browsers will not show you an error for this. They will repair it, following a fixed recovery algorithm, and give you a DOM that is valid but not the one you meant. That is why broken nesting so often shows up as a styling bug rather than as an obvious failure: your CSS rule targets a structure that no longer exists the way you wrote it. Open Developer Tools and compare the tree with your file whenever something styles strangely for no visible reason.
The practical defence is indentation. Indent every nested element by two spaces, and misaligned closing tags become visible at a glance. Most editors will also highlight the matching tag when your cursor is on one, and will warn you about an unclosed element — which is reason enough to move off Notepad early.
<!-- Correct nesting: strong opens last, closes first -->
<p>The deadline is <strong>Friday</strong>.</p>
<!-- Broken nesting: overlapping elements -->
<p>The deadline is <strong>Friday</p></strong>
<!-- Correct nesting of a list inside a list item -->
<ul>
<li>Semester 1
<ul>
<li>Data Structures</li>
<li>Digital Logic</li>
</ul>
</li>
<li>Semester 2</li>
</ul> - A free way to catch these mistakes: paste your page into the W3C Markup Validation Service at
validator.w3.org. It reports unclosed tags, bad nesting and invalid attributes in plain language, and it is the fastest debugging tool a beginner has.
Block Elements and Inline Elements
Elements fall into two broad behaviours, and understanding the difference explains most of the layout surprises beginners hit. A block-level element starts on a new line and, by default, stretches across the full width available to it. Headings, paragraphs, lists and <div> all behave this way. An inline element does not start a new line; it sits inside a line of text and takes up only as much width as its content needs. Links, <strong>, <em>, <img> and <span> behave this way.
This is why two paragraphs stack vertically while two links sit side by side in the same sentence, without you writing any CSS at all. It is also why setting a top and bottom margin on a <span> appears to do nothing: inline elements ignore vertical margins by default.
The rule of thumb that follows is about what may contain what. A block element can contain both other block elements and inline elements. An inline element should only contain other inline elements and text. Putting a heading inside a <strong> is upside down — mark the heading first, and put the emphasis inside it if you need it.
<!-- Block: each starts on its own line, full width -->
<h2>Club Members</h2>
<p>Second-year students only.</p>
<div>Meetings every Saturday.</div>
<!-- Inline: these flow inside the line of text -->
<p>Email <a href="mailto:club@example.com">the club</a> or read the
<strong>rules</strong> before you <em>register</em>.</p>
<!-- Right way round -->
<h2><em>Draft</em> schedule</h2>
<!-- Wrong way round -->
<em><h2>Draft schedule</h2></em> - Common block elements:
<p>,<h1>–<h6>,<div>,<ul>,<ol>,<li>,<table>,<form>,<section> - Common inline elements:
<a>,<span>,<strong>,<em>,<img>,<code>,<label>,<input> - Block elements may contain blocks and inlines; inline elements should contain only inlines and text
- CSS can override the default behaviour with
display, but the nesting rules of HTML itself do not change when you do
Why a div Cannot Live Inside a Paragraph
This is the single most confusing rule for beginners, and it is worth understanding rather than memorising. The HTML specification says a <p> element may contain only inline content. So the moment the browser is parsing a paragraph and meets an opening <div>, it does not report an error and it does not nest the div inside. It closes the paragraph for you, right there, and starts the div as a sibling.
Look at what that produces. You wrote one paragraph containing a div. The browser built a paragraph, then a div, then a second, empty paragraph made from your stray </p>. Now your CSS rule p { border: 1px solid; } draws a mysterious empty box on the page, and your JavaScript that expected one paragraph finds two. Nothing in the browser told you this happened; you have to look at the DOM in Developer Tools to see it.
The fix is almost always to reach for the right element instead of nesting the wrong one. If you need a block of content with a heading and some text, that block is a <div> or a <section>, and the paragraph goes inside it — not the other way round. If you only need to style part of a sentence, the element you want is <span>, which is inline and perfectly legal inside a paragraph.
<!-- What you wrote -->
<p>
Registration details
<div>Closes on Friday</div>
</p>
<!-- What the browser actually builds -->
<p>Registration details</p>
<div>Closes on Friday</div>
<p></p> <!-- an empty paragraph you never wrote -->
<!-- What you should have written -->
<div>
<p>Registration details</p>
<p>Closes on Friday</p>
</div>
<!-- Styling part of a sentence: span is inline, so this is fine -->
<p>Registration <span class="deadline">closes on Friday</span>.</p> - The same rule catches
<ul>,<table>,<h2>and<form>inside a paragraph. If you ever see an empty element appear in Developer Tools that you are sure you did not write, this auto-closing behaviour is nearly always the reason.
Habits Worth Building Now
HTML is a forgiving language, and that forgiveness is exactly why disciplined habits pay off. Tag names are case-insensitive, so <P> and <p> both work — but lowercase is the universal convention, and mixing cases makes a file harder to search. Attribute values can technically be written without quotes in some cases, but the moment a value contains a space it breaks, so quote everything, always.
The habit that saves the most time is closing a tag the instant you open it, then filling in the content between. Type <ul></ul> first, then add the list items. You will never again spend twenty minutes hunting for the one closing tag you forgot in a two-hundred-line file.
- Write tag and attribute names in lowercase
- Always wrap attribute values in double quotes
- Close every tag as soon as you open it, then fill in the middle
- Indent nested content by two spaces so structure is visible
- Run the page through the W3C validator before you submit or deploy it
- When a layout behaves strangely, compare your file with the DOM in Developer Tools before changing any CSS
