What you’re styling when you style a ul
A <ul> is an unordered list: a wrapper around multiple <li> items.
When people say “CSS ul style”, they usually mean one of these things:
- Changing or removing the bullet (the marker).
- Adjusting indentation (how far the list is pushed in).
- Controlling spacing between items.
- Making the list look like a menu, checklist, or fancy component.
Most of the “list-ness” lives on the ul (marker type, marker position, indentation),
while most of the “item styling” lives on the li (spacing, borders, backgrounds, hover styles).
ul {
border: 2px dashed #111;
}
li {
background: #f2f2f2;
}
ul {
border: 2px dashed #111;
}
li {
background: #f2f2f2;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.demo-wrap {
max-width: 560px;
}
ul {
padding: 12px 12px 12px 40px;
margin: 0;
border-radius: 12px;
}
li {
padding: 8px 10px;
border-radius: 10px;
}
li + li {
margin-top: 8px;
}
Same markup, different targets: try activating each snippet.
- First item
- Second item
- Third item
Default ul behavior: bullets and indentation
By default, browsers give ul elements:
- A bullet marker (usually
disc). - Indentation (commonly left padding) so the bullets have room.
- Some margin above and below.
Different browsers and user agents can vary a bit. That’s why list styling often starts with resetting margin and padding to something intentional.
ul {
margin: 0;
padding: 0;
}
ul {
margin: 0;
padding-left: 1.25rem;
}
ul {
margin: 0;
padding-left: 2.5rem;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.demo {
max-width: 560px;
padding: 14px;
border: 2px solid #111;
border-radius: 14px;
}
li + li {
margin-top: 6px;
}
Indentation is mostly padding: switch snippets.
- Bullets need “breathing room”
- So padding-left is common
- And margin can be reset
CSS ul no bullet: removing bullets the right way
The classic “CSS ul remove bullet” is:
list-style: none; (or list-style-type: none;).
But removing bullets often leaves the indentation behind, because the list still has padding/margin. So in real life, you usually do both:
list-style: none;to remove the markerpadding-left: 0;(and sometimesmargin: 0;) to remove the indent
ul {
list-style: none;
}
ul {
list-style: none;
padding-left: 0;
}
ul {
list-style: none;
padding-left: 0;
margin: 0;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.panel {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul {
padding-left: 2rem;
margin: 12px 0;
}
li {
padding: 10px 12px;
border-radius: 12px;
background: #f2f2f2;
}
li + li {
margin-top: 8px;
}
Remove bullets: try each snippet and watch the leftover indent.
- Dashboard
- Billing
- Log out
A nice default reset for lists
If you’re building “menu lists” (nav, settings lists, etc.), this is a popular baseline:
- Remove bullets
- Remove default indentation
- Then add your own spacing on
li
ul.menu {
list-style: none;
padding-left: 0;
margin: 0;
}
ul.menu li {
padding: 10px 12px;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.card {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul.menu li {
background: #f2f2f2;
border-radius: 12px;
}
ul.menu li + li {
margin-top: 10px;
}
Menu-style UL: bullets removed, spacing controlled.
CSS ul list-style and list-style-type: the basics
The list-style shorthand can set multiple things at once, but beginners often start with
list-style-type, which chooses the marker shape.
Common unordered values:
disc, circle, square, and none.
ul {
list-style-type: disc;
}
ul {
list-style-type: circle;
}
ul {
list-style-type: square;
}
ul {
list-style-type: none;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.box {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul {
margin: 0;
padding-left: 2rem;
}
li + li {
margin-top: 6px;
}
list-style-type: click the snippets to swap bullet styles.
- Milk
- Eggs
- Chocolate (important)
list-style shorthand: quick example
The shorthand can include type and position (and historically an image).
This is valid:
list-style: square inside;
ul {
list-style: square outside;
}
ul {
list-style: square inside;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.demo {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul {
margin: 0;
padding-left: 2rem;
}
li {
background: #f2f2f2;
border-radius: 10px;
padding: 8px 10px;
}
li + li {
margin-top: 8px;
}
outside vs inside changes where the marker sits.
- This item wraps to a second line so you can see the difference clearly.
- This one also wraps to show alignment of the marker and text.
CSS ul indent: controlling indentation like a grown-up
Indentation is mostly a combo of:
padding-lefton theul(most common)marginon theul(space around the whole list)
If you’re trying to align lists with surrounding text, a predictable pattern is:
margin: 0; and set a deliberate padding-left.
ul {
padding-left: 32px;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.panel {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul {
margin: 0;
}
li + li {
margin-top: 6px;
}
.note {
padding: 10px 12px;
background: #f2f2f2;
border-radius: 12px;
margin-bottom: 12px;
}
Drag the slider to adjust indentation.
- First item aligns with something
- Second item wants consistency
- Third item definitely wants consistency
Removing indent completely without removing bullets
Sometimes you want bullets, but you want the list to align flush with the container. You can reduce padding-left to something small (not always zero) to keep the marker visible.
ul {
padding-left: 0.75rem;
}
ul {
padding-left: 0;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.frame {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul {
margin: 0;
}
li + li {
margin-top: 6px;
}
Careful: padding-left: 0 can make markers collide with the border.
- Marker needs space
- Even a tiny bit helps
- Use what looks good
CSS ul bullet style with ::marker
The ::marker pseudo-element targets the bullet/number itself.
This is the cleanest modern way to style bullets.
Great use cases:
- Change bullet color to match your theme
- Change marker content (for simple symbols)
- Make markers bolder
Reality check: ::marker styling is intentionally limited. Some properties won’t apply like you expect.
But for color and content, it’s fantastic.
ul li::marker {
color: #d10;
}
ul li::marker {
content: "→ ";
color: #111;
}
ul li::marker {
content: "✓ ";
color: #0a7;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.card {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul {
margin: 0;
padding-left: 32px;
}
li {
padding: 8px 10px;
border-radius: 12px;
background: #f2f2f2;
}
li + li {
margin-top: 8px;
}
::marker styles the bullet itself. Try the snippets.
- Write CSS
- Drink tea
- Celebrate tiny wins
Making markers “bigger” or spaced out
You can often affect marker size by changing the font properties on ::marker,
but results vary between browsers and fonts. A more reliable trick is to keep the marker simple,
and use padding on li for consistent spacing.
li::marker {
font-weight: 700;
}
li {
padding-left: 0.25rem;
}
li::marker {
content: "• ";
}
li {
padding-left: 0.4rem;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.wrap {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul {
margin: 0;
padding-left: 2rem;
}
li + li {
margin-top: 8px;
}
li {
background: #f2f2f2;
border-radius: 12px;
padding-top: 8px;
padding-bottom: 8px;
padding-right: 10px;
}
Tip: spacing is often easier with
lipadding than fighting the marker.
- Markers are special
- They don’t behave like normal elements
- So we use smart layout around them
When ::marker isn’t enough: custom bullets with ::before
If you want complete control (shapes, backgrounds, animation, positioning),
you’ll often remove the default bullets and draw your own with ::before.
This is common for:
- Icon bullets
- Badges
- Colored dots that align perfectly
ul {
list-style: none;
padding-left: 0;
margin: 0;
}
li {
display: grid;
grid-template-columns: 18px 1fr;
gap: 10px;
align-items: start;
}
li::before {
content: "";
width: 12px;
height: 12px;
margin-top: 9px;
border-radius: 999px;
background: #111;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.box {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
li {
padding: 10px 12px;
border-radius: 12px;
background: #f2f2f2;
}
li + li {
margin-top: 10px;
}
Custom bullets: remove default marker, draw your own.
- Much more control
- Consistent alignment
- Works great for “feature lists”
Learn more about ::before in the CSS ::before and ::after Pseudo-Elements Interactive Tutorial.
Custom bullets with emoji or text
You can also use text in content for quick wins.
Just keep it readable and don’t rely on super obscure symbols.
ul {
list-style: none;
padding-left: 0;
margin: 0;
}
li {
display: grid;
grid-template-columns: 26px 1fr;
gap: 10px;
align-items: start;
}
li::before {
content: "🔥";
line-height: 1;
margin-top: 2px;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.panel {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
li {
padding: 10px 12px;
border-radius: 12px;
background: #f2f2f2;
}
li + li {
margin-top: 10px;
}
Emoji bullets: great for playful UI lists.
- Spicy feature
- Even spicier feature
- Absolutely unhinged feature
CSS ul style: making the list look like a component
Once bullets and indent are handled, lists become a super useful layout tool. You can make them look like cards, menus, settings panels, or “to-do items”.
A common pattern:
- Reset the list
- Style
lilike rows - Add hover/focus styles if they behave like navigation
ul {
list-style: none;
padding-left: 0;
margin: 0;
}
li {
padding: 12px 14px;
border: 2px solid #111;
border-radius: 14px;
background: #fff;
}
li + li {
margin-top: 10px;
}
li:hover {
background: #f2f2f2;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.wrap {
max-width: 560px;
}
.small {
color: #333;
margin-top: 6px;
margin-bottom: 12px;
}
This looks like a “settings list”, but it’s just a ul with styled li.
- Appearance
- Privacy
- Integrations
Spacing and readability: line-height, padding, and gaps
Bullets are only half the story. Readability usually improves most when you control spacing.
- Use
li + lito add spacing between list items. - Use padding on
lifor “tap targets” (especially for mobile). - Use a comfortable
line-heightwhen list text wraps.
ul {
line-height: 1.4;
}
li + li {
margin-top: 10px;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.card {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul {
margin: 0;
padding-left: 2rem;
}
li {
background: #f2f2f2;
border-radius: 12px;
padding: 10px 12px;
}
Make wrapped items readable: adjust the sliders.
- A list item that wraps to the next line should still feel comfortable to read.
- Spacing between items helps scanning.
- Line height helps long text breathe.
Multi-column and nested ul tips
Two common “etc, etc” scenarios: multi-column lists and nested lists.
Multi-column ul
For simple “tag-like” or “link directory” lists, CSS columns can be handy. The marker stays with each item, and the browser flows items into columns.
ul {
columns: 2;
column-gap: 2rem;
}
ul {
columns: 3;
column-gap: 1.25rem;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.panel {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul {
margin: 0;
padding-left: 2rem;
}
li {
break-inside: avoid;
padding: 6px 0;
}
Columns: try 2 vs 3.
- Almond
- Banana
- Coconut
- Date
- Elderberry
- Fig
- Grape
- Honeydew
- Kiwi
Nested ul styling
Nested lists inherit a lot from their parent. You can:
- Change marker style at each level
- Adjust indentation for nested
ul - Add spacing so nesting feels intentional
ul ul {
list-style-type: circle;
}
ul ul {
list-style-type: square;
}
ul ul {
padding-left: 1.25rem;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.box {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul {
margin: 0;
padding-left: 2rem;
}
li + li {
margin-top: 6px;
}
ul ul {
margin-top: 6px;
}
Nested lists: style the inner
ul.
- Frontend
- HTML
- CSS
- JavaScript
- Backend
- APIs
- Databases
Common ul styling bugs and a debugging checklist
If your “CSS ul style” changes don’t show up, it’s usually one of these:
-
You removed bullets with
list-style: none, but indentation remains becausepadding-leftormarginis still there. -
You styled
::markerbut expected it to behave like a normal element. It’s limited on purpose. -
You styled the
ul, but the spacing problem is on theli(or vice versa). -
You’re targeting the wrong list (add a class to the
ulwhen needed).
Quick fix pattern for a “component list”: reset the list on the ul, then style the li intentionally.
ul.list {
list-style: none;
padding-left: 0;
margin: 0;
}
ul.list li {
padding: 12px 14px;
}
ul.list li + li {
margin-top: 10px;
}
*,
::before,
::after {
box-sizing: border-box;
}
body {
font-family: system-ui, Arial, sans-serif;
padding: 18px;
}
.shell {
max-width: 560px;
border: 2px solid #111;
border-radius: 14px;
padding: 14px;
}
ul.list li {
background: #f2f2f2;
border-radius: 14px;
}
Reliable component list baseline.
- Spacing is intentional
- Bullets are gone (by choice)
- Indentation is under control
Wrap-up: UL styling cheat sheet
- Remove bullets:
ul { list-style: none; } - Remove indent too:
ul { padding-left: 0; margin: 0; } - Change bullet type:
ul { list-style-type: square; } - Marker position:
ul { list-style-position: inside; } - Style bullets:
li::marker { color: ...; content: ...; } - Full control: remove bullets and use
li::before - Spacing:
li + li { margin-top: ...; }and padding onli
CSS UL Styling Conclusion
Lists are powerful and flexible, but their default styles can be a bit unpredictable.
With a few key properties and patterns, you can make your ul look exactly how you want,
whether that’s a simple bullet list or a polished menu component.
