Knowing how elements flow by default explains most surprises before you write any CSS.
By default, elements fall into two flow behaviours (CSS controls this through display, but the browser's defaults come from the element).
- Block-level elements such as
<p>,<h1>,<ul>,<section>and<div>start on a new line and stretch to the full available width. - Inline elements such as
<a>,<em>,<strong>,<span>,<code>and<img>sit inside a line of text and are only as wide as their content.
HTML also restricts what can go where. A <p> can only contain inline (phrasing) content: if you put a <div> or <ul> inside a paragraph, the parser closes the paragraph early and you get an empty <p> you didn't write. A <ul> may only have <li> children.
When no element describes your content, use the generic containers: <div> (block) and <span> (inline). They mean nothing; they exist as hooks for CSS classes and scripts. That's their strength and their danger. A page built only from <div> works visually but tells browsers, search engines and screen readers nothing about its structure.
So reach for a meaningful element first (heading, list, nav, button, article), and use <div> and <span> for purely presentational grouping, such as a wrapper you need for a flex layout or a span to colour one word.
Example
<div class="card"> <!-- block: full width, new line -->
<h2>Plan: <span class="accent">Pro</span></h2> <!-- span: inline hook -->
<p>Includes <strong>unlimited</strong> projects.</p>
</div>
<!-- What you wrote: -->
<p>Intro <div>Oops</div> text</p>
<!-- What the parser builds (p cannot contain a div):
<p>Intro </p><div>Oops</div> text<p></p> -->Remember
- Block elements start a new line and fill the width; inline ones flow in text
- p may only contain inline content
- div and span carry no meaning: use them only when nothing semantic fits
Watch out for
- Building whole pages from divs, which hides the structure from assistive technology.