Details
A detail contains answers to questions I have about confusing text.
The Details component contains helpful context for users but may not be necessary to display by default. It always follows complex text or lengthy descriptions.
Details
- Honeycrisp: Reveal molecule
- Customization: Design tokens and Styles
- Modifier:
.cfa-details
The visual appearance is modified using design tokens from the Honeycrisp Reveal molecule. Further customization is applied using the CSS modifier(s) .cfa-details
to add styles defined in a custom stylesheet.
Design tokens. Tokens define the name of basic system elements such as color, typography, or spacing. The values of tokens are relative to how the system defines them. This enables teams to alter the visual appearance of components yet remain within the system boundaries. Learn more about tokens on the Bixal's Design Tokens Guide.
Modifier. A modifier is a class name that applies a variant, type, or extended style customization to modify the component's visual appearance.
Examples
If you don't have any of these documents, you can write, sign, date, and submit this letter:
I, [your full name], work as a [your job]. I made $[monthly income] last month. Please use this letter as self-certification of my income.
[Your signature]
[Today's date]
The HTML for the demonstration above is rendered using context passed to the component's Thymeleaf template fragment. Learn how to include component templates for Thymeleaf and Ruby in the source and usage section.
<div class="cfa-details">
<button type="button" class="cfa-details__summary" data-js="details" data-aria-controls="aria-c-8f8d551dc2dec">
<span>What's an example of a self-certification letter?</span>
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img">
<use href="https://codeforamerica.github.io/uswds/assets/img/sprite.svg#chevron_right"></use>
</svg>
</button>
<div class="cfa-details__content" id="aria-c-8f8d551dc2dec">
<p>If you don't have any of these documents, you can write, sign, date, and submit this letter:</p>
<p>
<em>I, [your full name], work as a [your job]. I made $[monthly income] last month. Please use this letter as self-certification of my income.</em>
</p>
<p>
<em>[Your signature]</em>
<br>
<em>[Today's date]</em>
</p>
</div>
</div>
Context is the information necessary to configure and render a component template to HTML. It may include plain text strings, HTML, class names, IDs or other HTML attribute values. The context here is defined as JSON but the root attributes are translated to different variable syntaxes for Thymeleaf and Ruby templates. Learn how to pass these variables to each component template in the source and usage section.
{
"summary": "What's an example of a self-certification letter?",
"icon": "https://codeforamerica.github.io/uswds/assets/img/sprite.svg#chevron_right",
"controls": "aria-c-8f8d551dc2dec",
"body": "<p>If you don't have any of these documents, you can write, sign, date, and submit this letter:</p><p><em>I, [your full name], work as a [your job]. I made $[monthly income] last month. Please use this letter as self-certification of my income.</em></p><p><em>[Your signature]</em> <br> <em>[Today's date]</em></p>"
}
Guidance
Placement. The component always follows complex text or lengthy descriptions. This is because the content in the component should answer potential questions related to it’s preceding content.
Collapsed by default. There is a risk of users skipping content in the component. Therefore, it should never contain critical information if it is always closed by default.
Open by default, collapsed when revisiting. Ideally, the component is open by default. If the user leaves the screen containing the component and returns, then the component can be closed.
When to use something else.
Stacking collapsable sections of text. Accordions are used to consolidate long pages of text containing multiple headings. The Details component uses code that can’t be applied to this use case in a reliable way for screen reader users.
Long text blocks such as legal information. Text wells are used to contain extremely lengthy blocks of text. The Details component should contain shorter blocks of supplementary content.
Accessibility
Checklist Key
Design library component
Source and usage
- Sass stylesheet:
./_cfa-details.scss
- Thymeleaf template fragment:
./cfa-details.th.html
- Embedded Ruby (ERB) partial template:
./_cfa-details.html.erb
- JavaScript enables the expansion and collapse of the details region. It also toggles the ARIA expanded attribute on the summary button and the tabindex attribute on potentially focusable children inside the details region. The module can be found at
./cfa-details.js
. Guidance on individual module loading will added. Currently, there is one script that imports all modules. The source is located at@codeforamerica/js/index.js
. This entrypoint is compiled using Rollup.js and distributed to@codeforamerica/dist/js/default.js
.
Below is a demonstration of customizing the component theme settings. Refer to the theme and package-level settings documentation.
// Theme-level settings
@use 'cfa-uswds-theme' with (
// Global theme settings that affect the component, changing these will affect other components
$cfa-color-primary-lightest: 'mint-cool-5', // Affects details background
$cfa-color-primary-darker: 'mint-cool-80v' // Affects details text and border color
$cfa-small-font-size: '2xs' // Affects details font size
);
// Package-level settings
@use 'cfa-core' with (
$cfa-details-font-size: $theme-small-font-size,
$cfa-details-background-color: $theme-color-primary-lightest,
$cfa-details-text-color: $theme-color-primary-darker
);
This is the pre-rendered template fragment from the package. It is the same template used to render the demonstrations above. You may copy and paste from this example or use the template using the th:block th:replace
tag. See the example below.
<div th:fragment="details(modifier, summary, controls, openAttr, icon, body, text)" class="cfa-details" th:classappend="${modifier}">
<button type="button" th:if="${summary}" class="cfa-details__summary" data-js="details" th:attr="data-aria-controls=${controls},data-aria-expanded=${openAttr}">
<span th:text="${summary}">Summary</span><svg th:if="icon" class="usa-icon" aria-hidden="true" focusable="false" role="img">
<use th:href="${icon}"></use>
</svg>
</button>
<div th:attr="id=${controls}" th:if="${body}" class="cfa-details__content" th:utext="${body}"></div>
<div th:attr="id=${controls}" th:if="${text}" class="cfa-details__content">
<p th:text="${text}">Text</p>
</div>
</div>
Below is an example of how to use the fragment from the package directory using the th:block th:replace
inclusion tag. Replace the fragment parameters using your variables or context.
<th:block th:replace="~{packages/cfa-details/cfa-details.th :: details(${modifier}, ${summary}, ${controls}, ${openAttr}, ${icon}, ${body}, ${text})}" />
This is the pre-rendered partial template from the package. You may copy and paste from this example or use the template directly from the path.
<div class="cfa-details<% if defined?(modifier) %> <%= modifier %><% end %>">
<% if defined?(summary) %><button type="button" class="cfa-details__summary" data-js="details"<% if defined?(controls) %> data-aria-controls="<%= controls %>"<% end %><% if defined?(openAttr) %> data-aria-expanded="<%= openAttr %>"<% end %>>
<span><%= summary %></span><% if defined?(icon) %><svg class="usa-icon" aria-hidden="true" focusable="false" role="img">
<use href="<%= icon %>"></use>
</svg><% end %>
</button><% end %>
<% if defined?(body) %>
<div class="cfa-details__content"<% if defined?(controls) %> id="<%= controls %>"<% end %>><%= body %></div>
<% elsif defined?(text) %>
<div class="cfa-details__content"<% if defined?(controls) %> id="<%= controls %>"<% end %>><p><%= text %></p></div>
<% end %>
</div>
Below is an example of how to include the partial in a view from the package directory using the Ruby ERB
class. Replace the argument values using your variables or context. In a Rails environment, the render
method can be used instead with the same hash values.
<%= ERB.new(File.read('packages/cfa-details/_cfa-details.html.erb'), 0, 0, '@details').result_with_hash({modifier: modifier, controls: controls, openAttr: openAttr, summary: summary, icon: icon, body: body, text: text}) %>