안녕하세요! 프론트엔드 개발자의 길을 걷고 계신 여러분, 진심으로 환영합니다. 저는 여러분의 CSS 학습을 더 쉽고 재미있게 만들어드릴 강사입니다.
오늘은 웹 페이지에서 정말, 진짜, 너무나도 자주 쓰이는 리스트(목록) 스타일링(Styling lists)에 대해 알아볼 거예요. 공식 문서가 영어라 조금 막막하셨을 텐데, 제가 하나도 빠짐없이 번역하면서 실무에서 진짜 어떻게 쓰이는지 꿀팁까지 팍팍 얹어드릴 테니 잘 따라와 주세요!
리스트(목록)은 대부분의 경우 일반 텍스트와 똑같이 동작합니다. 하지만 리스트에만 적용되는 특별한 CSS 속성들이 몇 가지 있어서 꼭 알아두셔야 해요. 더불어 실무에서 알아두면 좋은 모범 사례(best practices)들도 함께 살펴보겠습니다. 이번 글에서 모든 걸 속 시원히 설명해 드릴게요.
| 선행 조건 (Prerequisites): | HTML로 콘텐츠 구조화하기 및 CSS 스타일링 기초 지식. |
| 학습 목표 (Learning outcomes): |
|
먼저 간단한 리스트 예제부터 살펴보겠습니다. 이 글을 진행하는 동안 우리는 순서 없는 리스트(unordered list), 순서 있는 리스트(ordered list), 그리고 설명 리스트(description list)를 모두 다룰 거예요. 이 리스트들은 모두 비슷한 스타일링 기능들을 가지고 있으면서도, 각자만의 독특한 특징도 가지고 있답니다. 스타일이 적용되지 않은 날것의 예제는 GitHub에서 확인하실 수 있습니다. (소스 코드도 한 번 구경해 보세요.)
우리 예제의 HTML 코드는 다음과 같습니다:
<h2>Shopping (unordered) list</h2>
<p>
Paragraph for reference, paragraph for reference, paragraph for reference,
paragraph for reference, paragraph for reference, paragraph for reference.
</p>
<ul>
<li>Hummus</li>
<li>Pita</li>
<li>Green salad</li>
<li>Halloumi</li>
</ul>
<h2>Recipe (ordered) list</h2>
<p>
Paragraph for reference, paragraph for reference, paragraph for reference,
paragraph for reference, paragraph for reference, paragraph for reference.
</p>
<ol>
<li>Toast pita, leave to cool, then slice down the edge.</li>
<li>
Fry the halloumi in a shallow, non-stick pan, until browned on both sides.
</li>
<li>Wash and chop the salad.</li>
<li>Fill pita with salad, hummus, and fried halloumi.</li>
</ol>
<h2>Ingredient description list</h2>
<p>
Paragraph for reference, paragraph for reference, paragraph for reference,
paragraph for reference, paragraph for reference, paragraph for reference.
</p>
<dl>
<dt>Hummus</dt>
<dd>
A thick dip/sauce generally made from chick peas blended with tahini, lemon
juice, salt, garlic, and other ingredients.
</dd>
<dt>Pita</dt>
<dd>A soft, slightly leavened flatbread.</dd>
<dt>Halloumi</dt>
<dd>
A semi-hard, unripened, brined cheese with a higher-than-usual melting
point, usually made from goat/sheep milk.
</dd>
<dt>Green salad</dt>
<dd>That green healthy stuff that many of us just use to garnish kebabs.</dd>
</dl>
지금 바로 라이브 예제를 열어서 브라우저 개발자 도구로 리스트 요소들을 요리조리 뜯어보면, 몇 가지 '기본 스타일(styling defaults)'이 적용되어 있는 걸 발견하실 수 있을 거예요:
<ul> 과 <ol> 요소는 위아래로 16px (1em)의 margin(바깥 여백)을 가지고 있고, 왼쪽에 40px (2.5em)의 padding-left(안쪽 여백)를 가지고 있습니다. 만약 아랍어나 히브리어처럼 글자가 오른쪽에서 왼쪽으로 써지는(rtl) 방향성 속성(dir)이 적용되었다면, 왼쪽 대신 padding-right가 40px (2.5em)로 적용됩니다.<li> 요소들은 간격에 대한 기본값이 따로 설정되어 있지 않습니다.<dl> (설명 리스트) 요소는 위아래로 16px (1em)의 margin을 갖지만, 패딩(padding)은 설정되어 있지 않습니다.<dd> (설명 데이터) 요소들은 왼쪽에 40px (2.5em)의 margin-left를 가집니다.<p> (단락) 요소 역시 위아래로 16px (1em)의 margin을 갖습니다. 리스트 타입들과 똑같죠!💡 강사님의 실무 팁!
"어? 저는 리스트에 패딩이나 마진을 준 적이 없는데 왜 자기 맘대로 들어가 있죠?"
맞아요. 브라우저가 기본적으로 제공하는(User Agent) 스타일 때문입니다. 실무에서 네비게이션 바(GNB)나 드롭다운 메뉴를 만들 때는 보통 이<ul>태그를 쓰는데요, 저 기본 여백과 점(bullet) 모양이 레이아웃을 다 망가뜨리기 때문에 실무 코드에서는 항상 제일 먼저ul { list-style: none; padding: 0; margin: 0; }로 싹 다 초기화(Reset)하고 시작한답니다!
리스트를 스타일링할 때는 주변 요소들(단락이나 이미지 등)과 동일한 수직 간격(vertical spacing, 이걸 디자이너들은 종종 수직 리듬(vertical rhythm)이라고 불러요!)을 유지하도록 스타일을 조절해야 합니다. 또한 리스트 항목들끼리도 동일한 수평 간격을 유지하도록 신경 써야 하죠. (완성된 예제는 GitHub에서 확인하거나 소스 코드를 볼 수 있습니다.)
텍스트의 스타일과 간격을 맞추기 위해 사용된 CSS는 다음과 같습니다:
/* General styles */
html {
font-family: "Helvetica", "Arial", sans-serif;
font-size: 10px;
}
h2 {
font-size: 2rem;
}
ul,
ol,
dl,
p {
font-size: 1.5rem;
}
li,
p {
line-height: 1.5;
}
/* Description list styles */
dd,
dt {
line-height: 1.5;
}
dt {
font-weight: bold;
}
10px로 설정했습니다. 이 설정은 페이지의 모든 요소에 상속됩니다.rem)를 설정했습니다. 이렇게 하면 단락과 리스트들이 모두 똑같은 폰트 크기와 상하 여백을 가지게 되어, 페이지 전체의 수직 리듬을 일관성 있게 유지하는 데 큰 도움이 됩니다.line-height(줄 높이)를 1.5로 주었습니다. 즉, 문장과 문장 사이의 간격이 똑같아진다는 뜻이죠. 이 역시 시각적 안정감(수직 리듬)을 지키는 데 한몫합니다.dt)과 내용(dd)에도 아까와 똑같이 line-height: 1.5를 주었어요. 누누이 말씀드리지만, 디자인은 일관성이 생명입니다! 또한 설명 제목(dt)은 시각적으로 눈에 확 띄도록 굵게(bold) 만들었습니다.자, 리스트의 간격을 맞추는 전반적인 테크닉을 살펴봤으니, 이제 본격적으로 리스트에만 존재하는 전용 속성들을 파헤쳐 볼까요? <ul>이나 <ol> 요소에 설정할 수 있는, 꼭 알아야 할 3대장 속성이 있습니다:
list-style-type: 리스트 항목 앞에 붙는 '마커(bullet)'의 모양을 정합니다. 예를 들어 순서 없는 리스트에는 네모(square)나 빈 동그라미(circle)를 쓸 수 있고, 순서 있는 리스트에는 숫자(numbers), 알파벳(letters), 또는 로마 숫자(roman numerals) 등을 쓸 수 있습니다.list-style-position: 리스트 항목 시작 부분에 있는 마커가 콘텐츠 영역 '안쪽(inside)'에 있을지, 아니면 밖으로 튀어나와서 '바깥쪽(outside)'에 있을지를 정합니다.list-style-image: 기본으로 제공되는 점이나 숫자 대신, 여러분이 직접 만든 멋진 커스텀 이미지를 마커로 쓸 수 있게 해줍니다.위에서 말씀드린 대로, list-style-type 속성을 사용하면 불릿(마커)의 종류를 바꿀 수 있습니다. 우리 예제에서는 순서 있는 리스트(<ol>)에 대문자 로마 숫자(upper-roman)를 적용해 보았습니다:
ol {
list-style-type: upper-roman;
}
결과는 이렇게 나타납니다:

list-style-type 레퍼런스 페이지에 가보시면 생각보다 훨씬 다양하고 재밌는 옵션들이 많으니 꼭 한 번 확인해 보세요! (일본어, 히브리어 숫자 등등 별게 다 있답니다.)
list-style-position 속성은 불릿이 리스트 항목의 콘텐츠 텍스트 '안쪽(inside)'에 위치할지, 아니면 텍스트 시작 전 '바깥쪽(outside)'에 위치할지를 결정합니다. 기본값은 outside이며, 바로 위의 이미지에서 보셨듯이 불릿이 텍스트 박스 바깥으로 튀어나와 있죠.
이 값을 inside로 바꾸게 되면, 불릿이 텍스트 라인 안쪽으로 쏙 들어오게 됩니다:
ol {
list-style-type: upper-roman;
list-style-position: inside;
}

위 그림을 보면 inside를 썼을 때 긴 텍스트가 줄 바꿈이 되면 텍스트가 마커 아래쪽부터 다시 시작되는 걸 볼 수 있어요. outside일 때는 마커 공간이 완전히 독립적으로 존재해서 텍스트만 깔끔하게 떨어지죠. 레이아웃 짤 때 이 차이를 꼭 기억하세요!
list-style-image 속성을 쓰면 불릿 대신 아예 원하는 이미지를 박아넣을 수 있습니다. 문법도 아주 간단하죠:
ul {
list-style-image: url("star.svg");
}
하지만... 이 속성은 솔직히 말해서 이미지의 크기를 줄이거나, 위치를 미세하게 조정하는 등의 세밀한 컨트롤이 거의 불가능합니다.
💡 강사님의 실무 팁!
그래서 실무에서는list-style-image를 거의 쓰지 않습니다! 대신 우리가 이전 레슨(배경과 테두리)에서 배웠던background속성들을 활용하거나, 아니면::before가상 요소를 써서 아이콘을 직접 그려 넣는 방식을 99% 사용한답니다.
우리의 완성된 예제에서도 바로 그 background 속성들을 사용해서 순서 없는 리스트를 기가 막히게 꾸며봤습니다:
ul {
padding-left: 2rem;
list-style-type: none;
}
ul li {
padding-left: 2rem;
background-image: url("star.svg");
background-position: 0 0;
background-size: 1.6rem 1.6rem;
background-repeat: no-repeat;
}
여기서 우리가 한 마법 같은 일들을 하나씩 뜯어볼까요?
<ul>의 padding-left를 기본값인 40px에서 20px(2rem)로 줄였습니다. 그리고 리스트 항목(<li>)에도 똑같이 2rem의 패딩을 주었죠. 이렇게 하면 전체적으로는 다른 리스트나 문단들과 줄이 딱 맞으면서도, <li> 텍스트 왼쪽에 우리가 배경 이미지로 쓸 '별 모양'이 들어갈 넉넉한 공간(2rem)이 생기게 됩니다. 이렇게 안 하면 텍스트와 배경 이미지가 겹쳐버려서 아주 지저분해 보일 거예요.list-style-type은 none으로 꺼버렸습니다. 못생긴 기본 점 마커는 이제 안녕! 배경 이미지가 그 역할을 대신할 겁니다.<li> 항목마다 우리가 원하는 별 이미지를 배경으로 깔았습니다.background-image: 불릿으로 쓸 이미지 파일의 경로를 적어줍니다.background-position: 배경 이미지가 나타날 좌표를 정합니다. 0 0이라고 쓰면, 각 <li>의 완전 왼쪽 위(top left) 구석에 찰싹 붙어 나오게 됩니다.background-size: 배경 이미지의 크기를 정합니다. 마커는 글씨 크기랑 비슷하거나 살짝 작은 게 이쁘겠죠? 텍스트 여백을 위해 비워둔 2rem(20px) 공간 안에 쏙 들어가도록 크기를 1.6rem 1.6rem (16px)으로 잡았습니다. 그러면 아이콘과 텍스트 사이에 4px의 아주 적당한 여백이 생기게 된답니다. 완벽하죠?background-repeat: 배경 이미지는 기본적으로 여백이 찰 때까지 바둑판처럼 무한 반복되려고 합니다. 우리는 딱 하나만 보여줄 거니까 no-repeat으로 막아줍니다.이렇게 세팅하고 나면 짠! 아래처럼 너무나 귀여운 결과물이 나옵니다:

지금까지 배운 세 가지 속성(type, position, image)은 모두 list-style이라는 단 하나의 축약 속성(shorthand property)으로 합쳐서 쓸 수 있습니다. 예를 들어, 아래처럼 세 줄로 썼던 코드를:
ul {
list-style-type: square;
list-style-image: url("example.png");
list-style-position: inside;
}
이렇게 단 한 줄로 깔끔하게 바꿀 수 있어요:
ul {
list-style: square url("example.png") inside;
}
값의 순서는 전혀 상관없습니다. 아무렇게나 적으셔도 되고, 꼭 세 개를 다 적을 필요 없이 하나나 두 개만 적어도 됩니다. (생략된 값들은 알아서 기본값인 disc, none, outside로 설정된답니다). 만약 type과 image를 둘 다 적어두면 어떻게 될까요? 이미지를 우선으로 불러오되, 인터넷이 끊기거나 파일이 지워져서 이미지를 불러올 수 없는 최악의 상황이 오면 방어막(fallback)으로 지정해둔 type 모양이 대신 나타나게 됩니다. 똑똑하죠?
순서 있는 리스트(<ol>)를 쓰다 보면, 1부터 시작하는 평범한 방식 말고 다르게 숫자를 매기고 싶을 때가 생길 겁니다. 예를 들어 5부터 시작하거나, 숫자가 거꾸로 카운트다운 되거나, 혹은 건너뛰면서 세고 싶을 수 있죠. 이럴 때 HTML과 CSS가 제공하는 쏠쏠한 도구들이 있습니다.
HTML의 start 속성을 사용하면 리스트가 1이 아닌 다른 숫자부터 시작하도록 만들 수 있습니다.
<ol start="4">
<li>Toast pita, leave to cool, then slice down the edge.</li>
<li>
Fry the halloumi in a shallow, non-stick pan, until browned on both sides.
</li>
<li>Wash and chop the salad.</li>
<li>Fill pita with salad, hummus, and fried halloumi.</li>
</ol>
결과를 확인해 보면, 1, 2, 3, 4가 아니라 4, 5, 6, 7로 번호가 매겨지는 걸 볼 수 있습니다!
MDN Playground에서 직접 예제 코드 만져보기
이번엔 카운트다운을 해볼까요? HTML의 reversed 속성을 추가하면 숫자가 위로 올라가는 대신 아래로 줄어듭니다.
<ol start="4" reversed>
<li>Toast pita, leave to cool, then slice down the edge.</li>
<li>
Fry the halloumi in a shallow, non-stick pan, until browned on both sides.
</li>
<li>Wash and chop the salad.</li>
<li>Fill pita with salad, hummus, and fried halloumi.</li>
</ol>
이렇게 하면 4, 3, 2, 1 순서로 카운트다운이 됩니다.
MDN Playground에서 직접 예제 코드 만져보기
참고:
만약reversed리스트에 있는<li>항목의 개수가 시작 번호(start) 값보다 많다면 어떻게 될까요? 숫자는 0을 지나 마이너스(음수)로 계속 끝없이 내려간답니다.
리스트 전체가 아니라 특정 항목의 번호만 콕 집어서 바꾸고 싶다면 어떻게 할까요? 그럴 땐 <ol> 태그가 아니라 <li> 태그에 직접 value 속성을 달아주면 됩니다. 짝수로만 번호를 매겨볼까요?
<ol>
<li value="2">Toast pita, leave to cool, then slice down the edge.</li>
<li value="4">
Fry the halloumi in a shallow, non-stick pan, until browned on both sides.
</li>
<li value="6">Wash and chop the salad.</li>
<li value="8">Fill pita with salad, hummus, and fried halloumi.</li>
</ol>
이렇게 하면 우리가 지정한 2, 4, 6, 8 번호표가 예쁘게 붙게 됩니다.
MDN Playground에서 직접 예제 코드 만져보기
참고:
숫자가 아니라 알파벳이나 로마 숫자 같은 다른list-style-type을 쓰고 있더라도, HTML 태그의value속성에는 반드시 숫자(numerical values)를 적어주셔야 합니다. (예를 들어 'D'부터 시작하고 싶다면value="4"라고 적어야 해요!)
자, 이제 여러분이 직접 손을 움직여볼 시간입니다! 위에서 배운 내용들을 총동원해서 중첩된(nested) 리스트를 예쁘게 스타일링해 볼까요?
<ul>)의 마커를 네모 모양(square)으로 바꿔주세요.<li>)과 순서 있는 리스트(ol)의 항목들에 line-height를 그들의 폰트 크기의 1.5배로 넉넉하게 주세요.<ol>)의 마커를 소문자 알파벳(lower alphabetical)으로 바꿔주세요.혹시 뭔가 잘못 건드려서 코드가 엉망이 되었다면 MDN Playground에 있는 Reset 버튼을 눌러 초기화할 수 있습니다. 어떻게 해야 할지 감이 안 잡히신다면 아래의 숨겨진 정답 코드를 살짝 확인해 보셔도 좋습니다. 화이팅!
<ul>
<li>First, light the candle.</li>
<li>Next, open the box.</li>
<li>
Finally, place the three magic items in the box, in this exact order, to
complete the spell:
<ol>
<li>The book of spells</li>
<li>The shiny rod</li>
<li>The goblin statue</li>
</ol>
</li>
</ul>
MDN Playground에서 직접 예제 코드 만져보기
정답이 궁금하다면 여길 클릭해서 열어보세요!여러분이 작성하신 CSS 코드는 아마 아래와 비슷할 거예요:
ul {
list-style-type: square;
}
li {
line-height: 1.5;
}
ol {
list-style-type: lower-alpha;
}
고생 많으셨습니다! 리스트 스타일링은 관련된 몇 가지 기본 원칙과 전용 속성들만 꽉 잡고 나면 생각보다 정말 쉽고 재밌는 영역입니다. 다음 시간에는 리스트만큼이나 웹에서 무지막지하게 많이 쓰이는 링크(Link)를 스타일링하는 기술에 대해 알아보겠습니다. 준비되셨나요?
기여하는 방법 알아보기 (Learn how to contribute)
이 페이지의 마지막 수정일은 Oct 13, 2025 이며, MDN 기여자들(MDN contributors)에 의해 작성되었습니다.
끝까지 읽어주셔서 감사합니다. 실무에서도 리스트를 자유자재로 다루는 멋진 프론트엔드 개발자가 되시길 응원합니다! 질문이 있다면 언제든 편하게 남겨주세요.