New components (accordion, aside, steps, vertical tab sets, and explicit card header and footer directives),
links that open in a new tab, badge tooltips, a plain-CSS build with no Sass,
tab selections that persist across pages and visits, accessibility fixes, FontAwesome v6 support,
and Octicons v19.42.0. Sphinx 7.2 or later is now required.
Upgrade notes
-
Sphinx
>=7.2is required (Sphinx 7.0 and 7.1 are no longer supported); Python stays at>=3.11({pr}276). -
The
^^^and+++card separators are deprecated and warn by default.
They still render as before, but the first card in a document that uses them emits one
design.card_legacywarning, so a build run with-Wfails until you do one of two things:- move the header and footer into the new
card-headerandcard-footerdirectives
(or the one-line:header:and:footer:options), which need sphinx-design 0.8.0 or later; or - add
"design.card_legacy"tosuppress_warningsin yourconf.py.
Once every card is migrated, set
sd_card_legacy_separators = Falseto stop scanning for the separators.
The plan is to turn the separators off by default in 1.0 and remove them in 2.0;
the cards page has a migration table ({pr}294). - move the header and footer into the new
-
Tab selections persist in
localStorageinstead ofsessionStorage, so a chosen tab is remembered
across browsing sessions as well as across pages.
The storage key prefix is set by the newsd_tabs_storage_prefixoption;
set it to an empty string to disable persistence ({pr}284, {issue}103). -
Static assets are served through Sphinx's
html_static_path, only for HTML-format builders.
A_sphinx_design_staticdirectory left in an existing build directory by an earlier version is unused
and can be deleted ({pr}276). -
The stylesheet is plain CSS, generated without Sass.
The--sd-color-*-highlighthover and focus shades are now derived at runtime withcolor-mix()
(behind the old value as a static fallback), so overriding a--sd-color-*variable now also changes its hover shade ({pr}290). -
The private
sphinx_design._compat.findallhelper is removed; callnode.findall(...)directly ({pr}276).
The privateCardDirective._create_componentmethod is renamed_create_slot;
the old name stays as an alias for one release ({pr}294). -
sd-card-textis added only to the direct child paragraphs of a card or dropdown body, and is added to
a paragraph's classes instead of replacing them; paragraphs nested deeper (in admonitions, lists, nested tab sets)
no longer get it ({pr}278).
New
- ✨
accordiondirective: groupsdropdowns so that opening one closes the others,
using the browser's native<details name>behaviour with no JavaScript;:flush:renders it edge to edge
by {user}chrisjsewellin {pr}291 - ✨
asidedirective: a call-out box floated beside the body text (:align:,:width:),
rendered as a semantic<aside>in HTML and a plain titled container elsewhere
by {user}chrisjsewellin {pr}292({issue}97) - ✨
stepsandstepdirectives for numbered procedures, with CSS-only number markers on an ordered list,
:start:and:color:options by {user}chrisjsewellin {pr}293 - ✨
card-headerandcard-footerdirectives, and:header:and:footer:options,
for card and grid-item-card headers and footers: the card body is parsed once as ordinary content,
and errors in a header or footer report their own line (see the upgrade notes for the legacy separators)
by {user}chrisjsewellin {pr}294 - ✨ Vertical tab sets:
tab-setandtab-set-codetake:orientation: vertical, which stacks the labels
in a rail beside the selected panel from themdbreakpoint up
by {user}kdeldyckein {pr}304({issue}219) - ✨ Open links in a new tab: the
link-new-tabflag oncardandgrid-item-card, andnew-tabon
button-linkandbutton-ref, for URLs and internal references alike
by {user}dipinknairin {pr}298({issue}170) - ✨ Badge tooltips: badge roles accept a trailing
; tooltipsuffix, rendered as a native HTMLtitle;
for link and ref badges it applies after the explicittext <target>form, and\;escapes a literal semicolon
by {user}chrisjsewellin {pr}286({issue}81) - ✨ Every badge role (plain, line, link and ref, in every colour) accepts a
tooltiprole option,
so a reStructuredText custom role (.. role:: bdg-stable(bdg-success)with:tooltip:) or an extension
can preset a tooltip; a; tooltipsuffix still takes precedence
by {user}chrisjsewellin {pr}316 - ✨ A line block in
button-linkorbutton-reftext renders as separate lines
(<br />in HTML,\newline{}in LaTeX), each line its own gettext message
by {user}Cherith1222in {pr}308and {user}chrisjsewellin {pr}315({issue}156) - ✨ A URL fragment that targets a tab (e.g.
page.html#tab-name), or an element inside a tab panel,
opens that tab, on load and onhashchangeby {user}chrisjsewellin {pr}284({issue}239) - ✨ FontAwesome v6 roles (
fa-solid,fa-brands,fa-regular), and CSS loading via the new
sd_fontawesome_sourceandsd_fontawesome_cdn_urloptions (the supported path for FontAwesome Pro kits)
by {user}chrisjsewellin {pr}285({issue}174) - ✨
sd_fontawesome_versionmakes icon role names version-agnostic: any spelling (fas,fa-solid, ...)
can emit the FontAwesome"4","5"or"6"class scheme, so upgrading FontAwesome is a one-lineconf.pychange;
the default"as-named"keeps emitting the role name as before by {user}chrisjsewellin {pr}288({issue}174) - ✨
sphinx_design.testingmodule with thenormalize_doctree_xmlhelper, for downstream extensions'
doctree regression tests by {user}chrisjsewellin {pr}277({issue}260)
Improve
- 👌 Keyboard focus rings restored on tab labels, dropdown summaries, buttons and stretched-link cards
(with:focus-visible, so they do not show on mouse click) by {user}gabalafouin {pr}230, carried in {pr}283 - 👌 Each tab label carries an
aria-controlsattribute naming its panel
(this is not the full WAI-ARIA tabs pattern) by {user}chrisjsewellin {pr}283({issue}30) - 👌 The tab hover colour is the active colour at 80% opacity, so a hovered tab no longer looks selected
by {user}dchaudhari7177in {pr}303({issue}301) - 👌
sd_fontawesome_latexalso accepts"fontawesome5"(loadingfontawesome5.styand emitting\faIcon{...}),
resolving package clashes with themes that load it;TrueandFalsework as before
by {user}chrisjsewellin {pr}285({issue}242) - 👌 All
sd_*settings are declared in one typed configuration, and an invalid value warns
(design.config) and falls back to the default by {user}chrisjsewellin {pr}274 - 👌 Plain-CSS stylesheet generated by a dependency-free Python tool (no Sass or Node),
with the dead vendor-prefixed declarations removed by {user}chrisjsewellin {pr}290
Fix
- 🐛 Synced tabs stay in sync when activated by keyboard or click-and-drag
by {user}chrisjsewellin {pr}284({issue}46) - 🐛 A
tab-setwith children other thantab-itemwarns for each one and renders the valid tabs,
instead of crashing with aValueErrorby {user}chrisjsewellin {pr}258({issue}243) - 🐛 Comments, hyperlink targets and system messages inside
grid,card-carousel,tab-setandtab-set-code
no longer warn as invalid children, and targets are kept so references to them resolve,
including anchors to targets inside tabs by {user}chrisjsewellin {pr}271and {pr}275({issue}86) - 🐛 Buttons survive gettext translation: translated
button-linkandbutton-refkeep their styling and links
by {user}sneakers-the-ratin {pr}264, carried in {pr}270({issue}96, {issue}44, {issue}263) - 🐛
button-refkeeps whitespace in reference targets (so multi-word labels, such as those from
autosectionlabel, resolve;reftargets are lowercased like the:ref:role), and renders nested inline content
likebutton-linkby {user}chrisjsewellin {pr}281({issue}110, {issue}228) - 🐛 The card and grid-item-card
:link:option keeps whitespace in reference targets,
and lowercasesreftargets like the:ref:role by {user}chrisjsewellin {pr}282({issue}110) - 🐛 Messages and gettext locations for button text name its first content line in reStructuredText
(they named a later line, or the including page for a button in an included file)
by {user}chrisjsewellin {pr}315 - 🐛 Icon roles no longer leak SVG markup into toctree labels and the search index,
andarticle-infoicons regain theirsd-pr-2spacing by {user}chrisjsewellin {pr}279({issue}99, {issue}117) - 🐛 Dropdowns no longer overwrite user classes on their paragraphs with
sd-card-text
by {user}chrisjsewellin {pr}278({issue}40) - 🐛 Non-HTML builds no longer gain a spurious
_sphinx_design_staticdirectory
by {user}chrisjsewellin {pr}276({issue}200, {issue}235) - 🐛 The
sd_fontawesome_latexrow of the global options table no longer splits into an extra cell
by {user}yvonnefroehlichin {pr}297
Dependencies
- ⬆️ Sphinx
>=7.2,<10by {user}chrisjsewellin {pr}276 - ⬆️ Octicons v19.8.0 to v19.42.0: 81 new icons (such as
agent,library,releaseandsparkle),
12 redrawn icons and 37 extra sizes; no icon is removed (commitstays available)
by {user}kdeldyckein {pr}309 - ⬆️ Theme extras refreshed to current releases by {user}
chrisjsewellin {pr}267,
and thetheme-pydataextra allowspydata-sphinx-theme<0.25({pr}313) - ⬆️ The build backend allows
flit_core>=3.4,<5by {user}chrisjsewellin {pr}312
Docs
- 📚 Buttons are documented as links styled as buttons, with an accessibility note
by {user}gabalafouin {pr}158, carried in {pr}287 - 📚 Sizing classes, multiple grid rows, links to synchronised tabs, and the MyST extensions the examples need
by {user}chrisjsewellin {pr}273({issue}172, {issue}122, {issue}184, {issue}247) - 📚 A browser support policy (Baseline Widely Available) and a "Design: the CSS pipeline" page
by {user}chrisjsewellin {pr}290 - 📚 Fix a typo in the get started page by {user}
stefmolinin {pr}229
Internal
- 🔧 Releases are published to PyPI with trusted publishing, and every pull request builds and checks the
distributions by {user}chrisjsewellin {pr}311 - 🔧 CI compiles the documentation PDF by {user}
chrisjsewellin {pr}289 - ♻️ Remove the unused
OCTICON_VERSIONandOCTICON_CSSconstants by {user}ftnextin {pr}205, carried in {pr}266
Full changelog: v0.7.0...v0.8.0