Sidebar Widgets

Sidebar widgets are flexible containers that provide a lot of patterns that are helpful in a variety of sidebar uses.

Basic Style

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.

1
2
3
4
5
6
7
8
<div class="s-sidebarwidget">
    <div class="s-sidebarwidget--content d-block">
        <div class="fs-headline1 mb8 lh-sm"></div></div>
</div>
13,672,187
questions

Simple Items

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<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>
balpha contributed 6 edits
Paweł contributed 7 edits
Aaron Shekey contributed 3 edits

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.

Complex Items

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<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>
balpha
contributed 6 edits
joined 8 months ago
Paweł
contributed 7 edits
joined 1 year 10 months ago
Aaron Shekey
Aaron Shekey
contributed 3 edits
joined 5 months ago

Headers

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<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>
Stats
asked 4 years, 4 months ago
viewed 7,437 times
active 2 months ago

The s-sidebarwidget__small-bold-text modifier is available for headers to modify the text appearance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<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>

Alternative Colors

Three modifier classes are available for changing the background color of an s-sidebarwidget: s-sidebarwidget__yellow, s-sidebarwidget__blue, and s-sidebarwidget__green.

1
2
3
<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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<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>

Second-Level Navigation

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<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 &amp; Moderation</a>
        </li>
        <li class="s-sidebarwidget--item">
            <a href="…">Answering</a>
        </li>
    </ul>
</nav>

Header Actions

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<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>

Accordions

In order to create an accordion, i.e. to make part of the sidebar widget expandable / collapsible, you can do the following.

  • The s-sidebarwidget-header element that controls the accordion needs

    • a modifier class of s-sidebarwidget__collapsing-control in order to display the expander arrow

    • An aria-expanded attribute with value true or false; this is not only necessary for accessiblity, but also controls the rotation of the expander arrow. The value must be in sync with the wrapper’s is-collapsed class (see below).

    • an aria-label attribute that makes it clear that this is a collapsing control, unless this is already clear from the header’s text content

    • an aria-controls attribute whose value is the id of the s-collapsible (see below)

    • a non-negatvie tabindex, usually 0, so it can be focused via keyboard navigation

  • The (one or more) content elements that are meant to be collapsed must be wrapped in an element of class s-collapsible, which has the following properties:

    • This element must have an id, so it can be referred to by the header’s aria-controls attribute (see above).

    • If (and only if) the accordion is collapsed, this element has the state class is-collapsed. The presence of this class must be synchronized with the header’s aria-expanded value.

  • Directly inside this wrapper element there must be an element of class s-collapsible--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).

A note on the examples below: There is an additional js-collapsing-control class on the headers. This page includes JavaScript code that correctly handles keyboard and click events on elements with this class. We should eventually make such JavaScript functionality universally available together with the Stacks CSS, but currently this is not the case.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<div class="s-sidebarwidget">
    <div class="s-sidebarwidget--header s-sidebarwidget__small-bold_text
                s-sidebarwidget__collapsing-control js-collapsing-control"
                aria-expanded="true"
                aria-controls="recent-searches"
                aria-label="toggle recent searches"
                tabindex="0">
        <a class="s-sidebarwidget--action" href="…">
            Clear
        </a>
        2 Recent Searches
    </div>
    <div class="s-collapsible" id="recent-searches">
        <div class="s-collapsible--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>
Clear 2 Recent Searches