Sidebar nav
For more than ten destinations someone moves between while staying on the same screen.
Live preview
Source
<nav class="dc-sb" aria-label="설정 메뉴">
<p class="dc-sb__title" id="dc-sb-h1">계정</p>
<ul class="dc-sb__list" aria-labelledby="dc-sb-h1">
<li><a class="dc-sb__item" href="#" aria-current="page"><span class="dc-sb__icon" aria-hidden="true">●</span><span class="dc-sb__text">프로필</span></a></li>
<li><a class="dc-sb__item" href="#"><span class="dc-sb__icon" aria-hidden="true">◐</span><span class="dc-sb__text">알림</span><span class="dc-sb__badge">3</span></a></li>
<li><a class="dc-sb__item" href="#"><span class="dc-sb__icon" aria-hidden="true">◆</span><span class="dc-sb__text">보안</span></a></li>
</ul>
<details class="dc-sb__group" open>
<summary class="dc-sb__grouphead"><span class="dc-sb__text">결제</span><span class="dc-sb__caret" aria-hidden="true">▾</span></summary>
<ul class="dc-sb__list">
<li><a class="dc-sb__item dc-sb__item--sub" href="#"><span class="dc-sb__text">요금제</span></a></li>
<li><a class="dc-sb__item dc-sb__item--sub" href="#"><span class="dc-sb__text">영수증</span></a></li>
</ul>
</details>
<hr class="dc-sb__sep">
<a class="dc-sb__item dc-sb__item--quiet" href="#"><span class="dc-sb__icon" aria-hidden="true">↪</span><span class="dc-sb__text">로그아웃</span></a>
</nav>
.dc-sb {
width: 248px; padding: var(--dc-3);
background: var(--dc-surface);
border-right: 1px solid var(--dc-line);
font-family: var(--dc-font);
}
.dc-sb__title {
margin: var(--dc-2) var(--dc-2) var(--dc-1);
color: var(--dc-text-mute); font-size: 12px; font-weight: 700; letter-spacing: .02em;
}
.dc-sb__list { list-style: none; margin: 0; padding: 0; }
.dc-sb__item {
display: flex; align-items: center; gap: var(--dc-3);
min-height: 40px; padding: 0 var(--dc-2);
border-radius: var(--dc-r-sm);
color: var(--dc-text-sub); text-decoration: none;
font-size: 14px; font-weight: 600;
transition: background var(--dc-fast), color var(--dc-fast);
}
.dc-sb__item:hover { background: var(--dc-sunken); color: var(--dc-text); }
.dc-sb__item[aria-current="page"] {
background: var(--dc-brand-soft); color: var(--dc-brand-text); font-weight: 700;
}
.dc-sb__icon { flex: 0 0 18px; width: 18px; text-align: center; font-size: 13px; }
.dc-sb__text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dc-sb__badge {
flex: 0 0 auto; min-width: 20px; padding: 0 6px;
border-radius: var(--dc-r-full);
background: var(--dc-danger-soft); color: var(--dc-danger);
font-size: 12px; font-weight: 700; text-align: center; line-height: 20px;
}
.dc-sb__group { margin-top: var(--dc-2); }
.dc-sb__grouphead {
display: flex; align-items: center; justify-content: space-between;
min-height: 40px; padding: 0 var(--dc-2);
border-radius: var(--dc-r-sm);
color: var(--dc-text); font-size: 14px; font-weight: 700;
cursor: pointer; list-style: none;
}
.dc-sb__grouphead::-webkit-details-marker { display: none; }
.dc-sb__grouphead:hover { background: var(--dc-sunken); }
.dc-sb__caret { color: var(--dc-text-sub); font-size: 11px; transition: transform var(--dc-fast); }
.dc-sb__group[open] .dc-sb__caret { transform: rotate(180deg); }
.dc-sb__item--sub { padding-left: var(--dc-6); font-weight: 600; }
.dc-sb__item--quiet { color: var(--dc-text-mute); }
.dc-sb__sep { height: 1px; margin: var(--dc-3) 0; border: 0; background: var(--dc-line); }
.dc-sb--rail {
display: flex; flex-direction: column; align-items: center; gap: var(--dc-1);
width: 76px; padding: var(--dc-2);
}
.dc-sb__item--rail {
justify-content: center; width: 44px; height: 44px; min-height: 44px;
padding: 0; gap: 0; font-size: 15px;
}
.dc-sb-shell {
display: flex; align-items: stretch;
border: 1px solid var(--dc-line); border-radius: var(--dc-r-md);
background: var(--dc-bg); overflow: hidden;
}
.dc-sb-shell__main { flex: 1 1 auto; min-width: 0; padding: var(--dc-5); }
.dc-sb-shell__h { margin: 0 0 var(--dc-2); color: var(--dc-text); font-size: 16px; font-weight: 700; }
.dc-sb-shell__p { margin: 0; color: var(--dc-text-sub); font-size: 14px; line-height: 1.65; }
@media (max-width: 700px) {
.dc-sb-shell { flex-direction: column; }
.dc-sb-shell .dc-sb { width: 100%; border-right: 0; border-bottom: 1px solid var(--dc-line); }
}
How to use it
- Past three groups, add section titles and keep each group to five items
- Mark the current item with aria-current="page" and with a background, not text color alone
- Build collapsible groups from details so they open and close without script
Watch out for
- In the icon-only rail keep every label in a dc-sr span; an icon alone is unreadable
- Below 1024px turn the sidebar into a drawer; squeezing both columns ruins both