Sidebar widgets
Sidebar widgets are flexible containers that provide a lot of patterns that are helpful in a variety of sidebar uses.
In its simplest form, the sidebar widget is an element with class .s-sidebarwidget
and a child of class .s-sidebarwidget--content
.
This sets up a sidebar widget with the appropriate inner spacing, and you can put into it whatever you want.
By default the content is a flex container. If you require display: block
instead, add the d-block
class.
<div class="s-sidebarwidget">
<div class="s-sidebarwidget--content d-block">
<div class="fs-headline1 mb8 lh-sm">
…
</div>
…
</div>
</div>
Oftentimes, your widget will be a list of similar, relatively simple items. By giving the s-sidebarwidget--content
a modifier class s-sidebarwidget__items
, and giving the items a class of s-sidebarwidget--item
, the content will be spaced out nicely.
In this case, each item is a flex container by default. If you require display: block
instead, specifically add the d-block
class to the s-sidebarwidget--item
, or add the s-sidebarwidget__block-items
modifier class to the s-sidebarwidget--content
to make the change to all items.
<div class="s-sidebarwidget">
<div class="s-sidebarwidget--content s-sidebarwidget__items">
<div class="s-sidebarwidget--item">
<img src="…" class="bar-sm mr8">
<span><strong>balpha</strong> contributed 6 edits</span>
</div>
<div class="s-sidebarwidget--item">
<img src="…" class="bar-sm mr8">
<span><strong>Paweł</strong> contributed 7 edits</span>
</div>
<div class="s-sidebarwidget--item">
<img src="…" class="bar-sm mr8">
<span><strong>Aaron Shekey</strong> contributed 3 edits</span>
</div>
</div>
</div>
There is built-in support for table
content. The table
element should have the classes s-sidebarwidget--content s-sidebarwidget__items
, and the tr
elements should be s-sidebarwidget--item
.
If your items are more complex than that, whitespace may not be enough to separate them clearly. In this case instead of a single s-sidebarwidget--content
element with multile items, use multiple s-sidebarwidget--content
elements, which will be separated by subtle divider lines.
<div class="s-sidebarwidget">
<div class="s-sidebarwidget--content">
<img src="…" class="bar-sm mr8">
<div class="lh4">
<strong>balpha</strong><br>
contributed 6 edits<br>
joined 8 months ago
</div>
</div>
<div class="s-sidebarwidget--content">
<img src="…" class="bar-sm mr8">
<div class="lh4">
<strong>Paweł</strong><br>
contributed 7 edits<br>
joined 1 year 10 months ago
</div>
</div>
<div class="s-sidebarwidget--content">
<img src="…" class="bar-sm mr8">
<div class="lh4">
<strong>Aaron Shekey</strong><br>
contributed 3 edits<br>
joined 5 months ago
</div>
</div>
</div>
Besides s-sidebarwidget--content
, the other possible child class is s-sidebarwidget--header
, which unsurprisingly creates a header. Headers can be used both as a title for the widget, as well as to create several sections inside the widget.
<div class="s-sidebarwidget">
<div class="s-sidebarwidget--header">
Stats
</div>
<table class="s-sidebarwidget--content s-sidebarwidget__items">
<tbody>
<tr class="s-sidebarwidget--item">
<td class="tc-black-350">asked</td>
<td>4 years, 4 months ago</td>
</tr>
<tr class="s-sidebarwidget--item">
<td class="tc-black-350">viewed</td>
<td>7,437 times</td>
</tr>
<tr class="s-sidebarwidget--item">
<td class="tc-black-350">active</td>
<td>2 months ago</td>
</tr>
</tbody>
</table>
</div>
The s-sidebarwidget__small-bold-text
modifier is available for headers to modify the text appearance.
<div class="s-sidebarwidget">
<div class="s-sidebarwidget--header s-sidebarwidget__small-bold-text">
Stats
</div>
<table class="s-sidebarwidget--content s-sidebarwidget__items">
<tr class="s-sidebarwidget--item">
<td class="tc-black-350">created</td>
<td>9 years, 1 month ago</td>
</tr>
</table>
<div class="s-sidebarwidget--header s-sidebarwidget__small-bold-text">
Recent Hot Answers
</div>
<ul class="s-sidebarwidget--content s-sidebarwidget__items">
<li class="s-sidebarwidget--item"><a href="…">…</a></li>
</ul>
</div>
Three modifier classes are available for changing the background color of an s-sidebarwidget
: s-sidebarwidget__yellow
, s-sidebarwidget__blue
,
and s-sidebarwidget__green
.
<div class="s-sidebarwidget s-sidebarwidget__yellow">…</div>
<div class="s-sidebarwidget s-sidebarwidget__green">…</div>
<div class="s-sidebarwidget s-sidebarwidget__blue">…</div>
A common use for sidebar widgets is as a navigation block or table of contents, including a highlight of the page that the user is currently looking at.
The recommended pattern, as shown in the example below, is to make the s-sidebarwidget
a nav
element, and for each group of links to create a ul
with the classes s-sidebarwidget--content s-sidebarwidget__items
, within which each li
is of class s-sidebarwidget--item
.
The currently active navigation item should have the aria-current
attribute set to "page"
(if it is a direct link to the very page that the user is looking at) or "true"
(in all other cases, e.g. if it is a link to a page that is conceptually a parent or the current page). This aria-current
attribute can be on the li
or on the a
.
<nav class="s-sidebarwidget">
<div class="s-sidebarwidget--header">
Personal Information
</div>
<ul class="s-sidebarwidget--content s-sidebarwidget__items">
<li class="s-sidebarwidget--item">
<a href="…">
…
</a>
</li>
<li class="s-sidebarwidget--item" aria-current="page">
<a href="…">
…
</a>
</li>
</ul>
<div class="s-sidebarwidget--header">
Site Settings
</div>
<ul class="s-sidebarwidget--content s-sidebarwidget__items">
<li class="s-sidebarwidget--item">
<a href="…">Preferences</a>
</li>
<li class="s-sidebarwidget--item">
<a href="…">Flair</a>
</li>
</ul>
</nav>
If you have a second level of navigation, you can add a ul
of class -subnav
to the top-level item. Highlighting the currently active navigation is a little more constrained in this case:
If the currently active top-level element has a subnavigation, the top-level aria-current
must be on the a
, not the li
.
The currently active second-level element must have its aria-current
on the li
, not the a
.
<nav class="s-sidebarwidget">
<ul class="s-sidebarwidget--content s-sidebarwidget__items">
<li class="s-sidebarwidget--item">
<a href="…">Asking</a>
</li>
<li class="s-sidebarwidget--item d-block">
<a href="…" aria-current="true">Our model</a>
<ul class="s-sidebarwidget--subnav">
<li>
<a href="…">Be nice</a>
</li>
<li aria-current="page">
<a href="…">What kind of behavior is expected of users?</a>
</li>
<li>
<a href="…">How do I find topics I’m interested in?</a>
</li>
</ul>
</li>
<li class="s-sidebarwidget--item">
<a href="…">Reputation & Moderation</a>
</li>
<li class="s-sidebarwidget--item">
<a href="…">Answering</a>
</li>
</ul>
</nav>
There is often a need for a header to contain a link or link-like clickable that refers to the whole widget or to the section that this header starts. We call this an “action link”, and it’s created by adding the class s-sidebarwidget--action
.
This link must come before the header text, otherwise it will not be placed correctly should the header ever wrap to multiple lines.
<div class="s-sidebarwidget">
<div class="s-sidebarwidget--header">
<a class="s-sidebarwidget--action" href="…">
Edit
</a>
Watched Tags
</div>
<div class="s-sidebarwidget--content">
<div class="grid gs4">
<a class="grid--cell s-tag" href="…">css</a>
<a class="grid--cell s-tag" href="…">html</a>
<a class="grid--cell s-tag" href="…">accessibility</a>
</div>
</div>
</div>
In order to create an accordion, i.e. to make part of the sidebar widget expandable / collapsible, you can make use of the s-expandable
component.
The s-sidebarwidget-header
element that controls the accordion needs a modifier class of s-sidebarwidget__expanding-control
in order to display the expander arrow. Beyond that, it needs all the attributes as described for the controlling button in the expandable documentation.
The (one or more) content elements that are meant to be collapsed must be wrapped in the s-expandable
element; inside this wrapper element there is the s-expandable--content
. This can be the same element as the s-sidebarwidget--content
element (if there’s only one content element that is meant to be collapsed), or it can be an additional wrapper element around the content element(s).
<div class="s-sidebarwidget">
<div class="s-sidebarwidget--header s-sidebarwidget__small-bold_text
s-sidebarwidget__expanding-control"
aria-expanded="true"
aria-controls="recent-searches"
aria-label="toggle recent searches"
data-controller="s-expandable-control"
tabindex="0">
<a class="s-sidebarwidget--action" href="…">
Clear
</a>
2 Recent Searches
</div>
<div class="s-expandable" id="recent-searches">
<div class="s-expandable--content">
<table class="s-sidebarwidget--content s-sidebarwidget__items">
<tr class="s-sidebarwidget--item">
<td>…</td>
<td>
<a href="…">remote jobs</a>
</td>
</tr>
<tr class="s-sidebarwidget--item">
<td>…</td>
<td>
<a href="…">…</a>
</td>
</tr>
</table>
</div>
</div>
</div>