diff --git a/.gitignore b/.gitignore index 8483ed852..a4d763580 100644 --- a/.gitignore +++ b/.gitignore @@ -121,3 +121,6 @@ profile.svg # Compiled translation files (are compiled at build time) src/pydata_sphinx_theme/locale/*/*/*.mo + +# jupyterlite db +.jupyterlite.doit.db diff --git a/docs/_static/custom.css b/docs/_static/custom.css index 10feae3a2..dea2ff828 100644 --- a/docs/_static/custom.css +++ b/docs/_static/custom.css @@ -25,13 +25,16 @@ /* begin-custom-color/* /custom.css */ div.admonition.admonition-olive { - border-color: olive; + border-color: hsl(60, 100%, 25%); } div.admonition.admonition-olive > .admonition-title:before { - background-color: olive; + background-color: hsl(60, 100%, 14%); } div.admonition.admonition-olive > .admonition-title:after { - color: olive; + color: hsl(60, 100%, 25%); +} +div.admonition.admonition-olive > .admonition-title { + color: white; } /* end-custom-color */ @@ -45,13 +48,16 @@ div.admonition.admonition-icon > .admonition-title:after { /* begin-custom-youtube/* /custom.css */ div.admonition.admonition-youtube { - border-color: #ff0000; /* YouTube red */ + border-color: hsl(0, 100%, 50%); /* YouTube red */ } div.admonition.admonition-youtube > .admonition-title:before { - background-color: #ff0000; + background-color: hsl(0, 99%, 18%); } div.admonition.admonition-youtube > .admonition-title:after { - color: #ff0000; + color: hsl(0, 100%, 50%); content: "\f26c"; /* fa-solid fa-tv */ } +div.admonition.admonition-youtube > .admonition-title { + color: white; +} /* end-custom-youtube */ diff --git a/docs/_templates/custom-template.html b/docs/_templates/custom-template.html index 0ed45ec1c..f6757f9d4 100644 --- a/docs/_templates/custom-template.html +++ b/docs/_templates/custom-template.html @@ -1,6 +1,6 @@ diff --git a/docs/community/contributors.md b/docs/community/contributors.md index c89ea336a..e9bd63555 100644 --- a/docs/community/contributors.md +++ b/docs/community/contributors.md @@ -17,4 +17,4 @@ Support and development for this theme has been funded by one [NumFocus Small De ## Theme logo -Thanks to [@drammock](https://github.com/drammock) for initial design of the theme logo. +Thanks to [@drammock](https://github.com/drammock) for the initial design of the theme logo. diff --git a/docs/community/practices/merge.md b/docs/community/practices/merge.md index 8bb91e9fe..03effa8ae 100644 --- a/docs/community/practices/merge.md +++ b/docs/community/practices/merge.md @@ -1,20 +1,20 @@ # Merge and review policy Our policy for merging and reviewing describes how we review one another's work, and when we allow others to merge changes into our main codebase. -It tries to balance between a few goals: +It tries to balance a few goals: - Iterate on PRs and merge them relatively quickly, so that we reduce the debt associated with long-lasting PRs. - Give enough time for others to provide their input and guide the PR itself, and to ensure that we aren't creating a problem with the PR. - Value iterative improvement over creating the perfect Pull Request, so that we do not burden contributors with cumbersome discussion and minor revision requests. - Recognize that we all have limited time and resources, and so cannot guarantee a full quality assurance process each time. -- Give general preference to the opinions from maintainers of projects in the PyData ecosystem, as a key stakeholder community of this theme. +- Give general preference to the opinions of maintainers of projects in the PyData ecosystem, as a key stakeholder community of this theme. -We follow these guidelines in order to achieve these goals: +We follow these guidelines to achieve these goals: - Assume that all maintainers are acting in good faith and will use their best judgment to make decisions in the best interests of the repository. -- We can and will make mistakes, and so encourage best practices in testing and documentation to guard against this. -- It's important to share information, so give a best effort at telling others about work that you're doing. -- It's best to discuss and agree on important decisions at a high level before implementation, so give a best effort at providing time and invitation for others to provide feedback. +- We can and will make mistakes, so encourage best practices in testing and documentation to guard against this. +- It's important to share information, so give your best effort at telling others about the work that you're doing. +- It's best to discuss and agree on important decisions at a high level before implementation, so give the best effort at providing time and invitation for others to provide feedback. ## Policy for moderate changes @@ -35,7 +35,7 @@ They can be merged when the above conditions are met, and one of these things ha These are changes that significantly alter the experience of the user, or that add significant complexity to the codebase. -All of the above, but PRs **must** have approval from at least one other core maintainer before merging. +All the above, but PRs **must** have approval from at least one other core maintainer before merging. In addition, the PR author should put extra effort into ensuring that the relevant stakeholders are notified about a change, so they can gauge its impact and provide feedback. ## Policy For minor changes and bugfixes diff --git a/docs/community/practices/release.md b/docs/community/practices/release.md index 4ae1d8331..6b4617a40 100644 --- a/docs/community/practices/release.md +++ b/docs/community/practices/release.md @@ -5,7 +5,7 @@ ## Our goals Our release policy describes how we decide when to make a new public release of the theme so that other projects may use new features and improvements. -It tries to balance between these goals: +It tries to balance these goals: - Release relatively frequently, so that we provide a continuous stream of improvement to projects that use the theme, and minimize the effort needed to upgrade. - Do not surprise people (especially with negative surprises) and provide time for projects to provide feedback about upcoming features. diff --git a/docs/community/practices/versions.md b/docs/community/practices/versions.md index c9202d965..18d7a7364 100644 --- a/docs/community/practices/versions.md +++ b/docs/community/practices/versions.md @@ -1,7 +1,7 @@ # Supported Python and Sphinx versions Python and Sphinx are the two primary dependencies of this theme. -We have special practices for deciding which versions of these we support (especially Sphinx, which tends to release breaking changes). +We have particular practices for deciding which versions of these we support (especially Sphinx, which tends to release breaking changes). ## Supported Python versions @@ -9,16 +9,16 @@ For releases of Python, we aim to follow this approach[^1]: > For a new major/minor release of this theme, we support any minor Python versions released in the last 3.5 years (42 months), as defined in [the EOL schedule for Python](https://endoflife.date/python)[^2]. -We define "support" as testing against each of these versions, so that users can be assured they will not trigger any bugs. +We define "support" as testing against each of these versions so that users can be assured they will not trigger any bugs. -For example, if we made a minor release tomorrow, we'd [look at the EOL schedule for Python](https://endoflife.date/python) and support all of the versions that fall within a 3.5 year window. +For example, if we made a minor release tomorrow, we'd [look at the EOL schedule for Python](https://endoflife.date/python) and support all the versions that fall within a 3.5-year window. [^1]: Our support for Python versions is inspired by [NEP 029](https://numpy.org/neps/nep-0029-deprecation_policy.html). -[^2]: These policies are goals, but not promises. We are a volunteer-led community with limited time. Consider these sections to be our intention, but we recognize that we may not always be able to meet these criteria if we do not have capacity to do so. We welcome contributions from others to help us more sustainably meet these goals! +[^2]: These policies are goals, not promises. We are a volunteer-led community with limited time. Consider these sections to be our intention, but we recognize that we may not always be able to meet these criteria if we cannot do so. We welcome contributions from others to help us more sustainably meet these goals! ## Supported Sphinx versions -For supporting versions of Sphinx, we aim to follow this approach: +For supported versions of Sphinx, we aim to follow this approach: > We support the latest released version of Sphinx that is **older than 6 months**. > We unofficially support earlier released versions of Sphinx, but may increase the lower-bound in our dependency pin without warning if needed[^2]. diff --git a/docs/community/setup.md b/docs/community/setup.md index 6777a53cd..6b0747666 100644 --- a/docs/community/setup.md +++ b/docs/community/setup.md @@ -18,7 +18,7 @@ of: For each pull request, the documentation is built and deployed to make it easier to review the changes in the PR. To access this, click on the {{ rtd }} preview in the CI/CD jobs. -The sections below cover the steps to do this in more detail. +The sections below cover the steps to take in more detail. ## Clone the repository diff --git a/docs/community/structure.md b/docs/community/structure.md index 9bd143bcf..f16297169 100644 --- a/docs/community/structure.md +++ b/docs/community/structure.md @@ -9,14 +9,14 @@ The content is written in a combination of reStructuredText and MyST Markdown. ## Location and structure of CSS/JS assets The CSS and JS for this theme are built for the browser from `src/pydata_sphinx_theme/assets/*` with -[webpack](https://webpack.js.org/). The main entrypoints are: +[webpack](https://webpack.js.org/). The main entry points are: -- CSS: `src/pydata_sphinx_theme/assets/styles/index.scss` +- CSS: `src/pydata_sphinx_theme/assets/styles/pydata-sphinx-theme.scss` - the main part of the theme assets - customizes [Bootstrap](https://getbootstrap.com/) with [Sass](https://sass-lang.com) -- JS: `src/pydata_sphinx_theme/assets/scripts/index.js` +- JS: `src/pydata_sphinx_theme/assets/scripts/pydata-sphinx-theme.js` - provides add-on Bootstrap features, as well as some custom navigation behavior diff --git a/docs/community/topics/assets.md b/docs/community/topics/assets.md index fa2c9e9cd..c893c6348 100644 --- a/docs/community/topics/assets.md +++ b/docs/community/topics/assets.md @@ -38,7 +38,7 @@ This is configured in the `webpack.config.js` file, and imported in the respecti ## FontAwesome icons Three "styles" of the [FontAwesome 6 Free](https://fontawesome.com/icons?m=free) -icon font are used for {ref}`icon links ` and admonitions, and is +icon font are used for {ref}`icon links ` and admonitions and is the only `vendored` font. - It is managed as a dependency in `package.json` @@ -50,7 +50,7 @@ the only `vendored` font. Our Webpack build generates a collection of [Jinja macros](https://jinja.palletsprojects.com/en/3.0.x/templates/#macros) in the `static/webpack-macros.html` file. -These macros are imported in the main `layout.html` file, and then inserted at various places in the page to link the static assets. +These macros are imported in the main `layout.html` file, and then inserted at various places on the page to link the static assets. -Some of the assets [are "preloaded"](https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload), meaning that the browser begins requesting these resources before they're actually needed. -In particular, our JavaScript assets are preloaded in ``, and the scripts are actually loaded at the end of ``. +Some assets [are "preloaded"](https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload), meaning that the browser begins requesting these resources before they're needed. +In particular, our JavaScript assets are preloaded in ``, and the scripts are loaded at the end of ``. diff --git a/docs/community/topics/bootstrap.rst b/docs/community/topics/bootstrap.rst index 58b548a10..c8e87aa6b 100644 --- a/docs/community/topics/bootstrap.rst +++ b/docs/community/topics/bootstrap.rst @@ -10,16 +10,16 @@ Dropping **JQuery** Bootstrap Dropped its **JQuery** dependency and rewrote plugins to be in regular JavaScript. Sphinx *v6* will do the same (https://github.com/sphinx-doc/sphinx/issues/10070). As a consequence, we also rewrote all our javascript to only use vanilla **JavaScript**. -Any documentation relying on **JQuery** in their ``custom.js`` files will need to rewrite it or specifically import **JQuery**. +Any documentation relying on **JQuery** in their ``custom.js`` files will need to rewrite or specifically import **JQuery**. Breaking changes ---------------- ‼️ Relevant for those using a ``custom.css`` and/or a ``custom.js`` file! -Bootstrap changed a number of CSS classes, so if you wrote custom rules of JS logic that depended on them, it may have changed. +Bootstrap changed several CSS classes, so if you wrote custom rules of JS logic that depended on them, it may have changed. -All of the changes from *v4* to *v5* are `listed in their documentation `_. +All the changes from *v4* to *v5* are `listed in their documentation `_. Below list the ones that had consequences on ``pydata-sphinx-theme`` components. Sass @@ -57,4 +57,4 @@ Utilities JavaScript ^^^^^^^^^^ -- Data attributes for all JavaScript plugins are now namespaced to help distinguish Bootstrap functionality from third parties and your own code. For example, we use ``data-bs-toggle`` instead of ``data-toggle``. +- Data attributes for all JavaScript plugins are now namespaced to help distinguish Bootstrap functionality from third parties and your code. For example, we use ``data-bs-toggle`` instead of ``data-toggle``. diff --git a/docs/community/topics/config.md b/docs/community/topics/config.md index 1f3323d0d..a78725470 100644 --- a/docs/community/topics/config.md +++ b/docs/community/topics/config.md @@ -8,7 +8,7 @@ Here are some tips to do this the "right" way in Sphinx. ## Update config: use `app.config` For example, `app.config.foo = "bar"`. -For some reason, when Sphinx sets things it directly uses `__dict__` but this doesn't seem to be different from the pattern described here. +For some reason, when Sphinx sets things it directly uses `__dict__`, but this doesn't seem to be different from the pattern described here. ## Update theme options: use `app.builder.theme_options` diff --git a/docs/community/topics/manual-dev.md b/docs/community/topics/manual-dev.md index 6736f1636..35964d5cc 100644 --- a/docs/community/topics/manual-dev.md +++ b/docs/community/topics/manual-dev.md @@ -51,7 +51,7 @@ $ sphinx-build docs docs/_build/html ## Compile web assets (JS/CSS) -To compile the javascript and CSS assets for the theme, run the following command: +To compile the JavaScript and CSS assets for the theme, run the following command: ```console $ stb compile @@ -59,7 +59,7 @@ $ stb compile This will compile everything in the `src/pydata_sphinx_theme/assets` folder and place them in the appropriate places in our theme's folder structure. -## Start a live-server to build and serve your documentation +## Start a live server to build and serve your documentation To manually open a server to watch your documentation for changes, build them, and display them locally in a browser, run this command: diff --git a/docs/user_guide/ablog.md b/docs/user_guide/ablog.md index 327b88c0f..19797b8e5 100644 --- a/docs/user_guide/ablog.md +++ b/docs/user_guide/ablog.md @@ -1,13 +1,13 @@ # Blogs with `ABlog` The [ABlog extension](https://ablog.readthedocs.io/) allows you to tag pages as **blog posts** and additionally include them in landing pages for your blog. -It also has a number of sidebar templates to show off collections of your posts. +It also has several sidebar templates to show off collections of your posts. :::{admonition} Minimum version ABlog v0.11.0 Make sure you have `ABlog>=0.11.0rc2` in your dependencies. ::: -This theme has styling support for ABlog, and demonstrates some of its functionality here. +This theme has styling support for ABlog and demonstrates some of its functionality here. ## Example blog diff --git a/docs/user_guide/accessibility.rst b/docs/user_guide/accessibility.rst index 40e30c4d5..5e4a26d00 100644 --- a/docs/user_guide/accessibility.rst +++ b/docs/user_guide/accessibility.rst @@ -2,17 +2,16 @@ .. meta:: :description lang=en: - The features and plans for addressing accessibility concerns on pydata-sphinx-theme + The features and plans for addressing accessibility concerns on the PyData Sphinx Theme. ************* Accessibility ************* -Creating and publishing content that does not exclude audiences with limited abilities -of various kinds is challenging, but also important, to achieve and then maintain. +Creating and publishing content that does not exclude disabled users is a complex and iterative task. -While there is no one-size-fits-all solution to maintaining accessible content, this -theme and documentation site use some techniques to avoid common content shortcomings. +While there is no one-size-fits-all solution to maintaining accessible content, the PyData Sphinx Theme +and this documentation site use some techniques to avoid common content shortcomings. .. Note:: @@ -27,27 +26,34 @@ Metadata ======== Several of our documentation pages contain metadata (i.e., ``.. meta::`` directives -in reStructuredText) giving brief summaries of the page contents. If you notice a +in reStructuredText) giving summaries of the page contents. If you notice a page that lacks metadata, please open a pull request to add it! Colors ====== -Our default code highlighting styles are ``a11y-high-contrast-light`` and -``a11y-high-contrast-dark`` from https://github.com/Quansight-Labs/accessible-pygments. -These styles are designed to be more accessible to users with limited visual abilities. -If you don't like the look of our default code highlighting styles, there are several more -to choose from at https://github.com/Quansight-Labs/accessible-pygments. - +* Our default code highlighting styles are ``a11y-high-contrast-light`` and + ``a11y-high-contrast-dark`` from https://github.com/Quansight-Labs/accessible-pygments. + These styles are designed to meet WCAG 2 AA or AAA contrast requirements. + If you don't like the look of our default code highlighting styles, there are several more + to choose from at https://github.com/Quansight-Labs/accessible-pygments. +* We recently revisited the PyData Sphinx theme color palette to ensure that + the colors we use meet WCAG 2 AA or AAA contrast requirements. +* We also re-defined our ``primary`` and ``secondary`` colors to be more accessible and distinct from semantic colors used + to denote success, warning, info, and danger contexts or information. +* We simplified the color palette and removed some colors that were problematic to meeting WCAG 2 AA or AAA contrast requirements + and for certain types of colorblindness. +* We have improved how we assign text colors to interactive elements such as buttons and dropdowns to ensure that they meet + WCAG 2 AA or AAA contrast requirements. What You Can Do ^^^^^^^^^^^^^^^ -In Configuration -================ +Site configuration +================== -Some minor configuration options in a site's ``conf.py`` can impact the +The following sections include recommendations for settings in the ``conf.py`` file that can positively impact the accessibility of content generated by this theme, and Sphinx in general. @@ -60,9 +66,9 @@ identify if the content is in a language the reader understands. .. Hint:: - Specifying a ``language`` will propagate to the top-level `html` tag. + Specifying a ``language`` will propagate to the top-level ``HTML`` tag. - .. code-block:: python + .. code-block:: Python language = "en" @@ -75,7 +81,7 @@ approach to telling programs like search engines and assistive technologies wher different content appears on a website. If using a service like `ReadTheDocs `__, these files -will be created for you *automatically*, but for some of the other approaches below, +will be created for you *automatically*, but for some other approaches below, it's handy to generate a `sitemap.xml` locally or in CI with a tool like `sphinx-sitemap `__. @@ -93,13 +99,22 @@ it's handy to generate a `sitemap.xml` locally or in CI with a tool like sitemap_url_scheme = "{link}" -In Your Source -============== +Logo best practices +-------------------- +If you use both light and dark themes, it's best to provide a logo that works well in both or to provide an alternative for the dark theme. +If you have a logo, you can add alt-text to it by adding the following to your +``conf.py``: -.. Note:: +.. code-block:: python + + "logo": { + "text": "PyData Theme", + "image_dark": "_static/logo-dark.svg", + "alt_text": "PyData Theme home", + }, - Stay tuned for more ideas here as we learn more working on this site! +Note the use of "home" in the alt text to indicate that the logo is also a link to the home page. In the Browser ============== @@ -113,32 +128,35 @@ Built-in tools Most major browsers, including `Firefox `__ -and `Chrome `__ -include significant accessibility tooling in their development experience. Exploring -these, and the modes they offer, can help to quickly pinpoint issues, and often -include links to standards. +and `Chrome `__, +have accessibility tools built-in as part of their web developer tools. +These tools can help to quickly identify accessibility issues and often include links to standards. tota11y ------- `tota11y `__ is an open source -"bookmarklet" which modifies the currently-loaded page in-place, and highlights -a number of accessibility issues. +"bookmarklet" which modifies the currently-loaded page in place, and highlights +several accessibility issues. WAVE ---- `WAVE `__ is a proprietary (but *gratis*) -browser extension which can highlight a large number of issues. +browser extension which can highlight multiple issues. +.. Warning:: + Note that automated testing and extensions such as the ones mentioned above will at best catch 30-40% of accessibility issues. + They are not a replacement for manual testing and having a perfect score on any of these tools does not mean that + the site can be used by disabled users but instead signals that it follows some accessibility best practices. In Continuous Integration ========================= -A number of automated tools are available for assessing *glaring* accessibility -issues across a number of pages at once, usually with many configurable options. +Several automated tools are available for assessing *glaring* accessibility +issues across some pages at once, usually with many configurable options. Lighthouse diff --git a/docs/user_guide/analytics.rst b/docs/user_guide/analytics.rst index c6ae09aa1..a6e2695f5 100644 --- a/docs/user_guide/analytics.rst +++ b/docs/user_guide/analytics.rst @@ -13,7 +13,7 @@ options depending on the analytics provider that you want to use. "analytics": analytics_options, } -Generally speaking we recommend using Plausible over Google Analytics because +Generally speaking, we recommend using Plausible over Google Analytics because it has a better story around user security and privacy. In addition, it is more open-source and transparent. In fact, `you can self-host a Plausible server `__. @@ -36,7 +36,7 @@ and privacy-friendly analytics for the site. To configure, you will need to prov - A URL pointing to the JavaScript analytics script that is served by your Plausible server - A domain that reflects where your documentation lives -Plausible's javascript will be included in all html pages to gather metrics. +Plausible's JavaScript will be included in all HTML pages to gather metrics. The dashboard with analytics results will be accessible at ``https:///``. .. code:: python @@ -56,9 +56,9 @@ Google Analytics ================ If the ``google_analytics_id`` config option is specified (like ``G-XXXXXXXXXX``), -Google Analytics' javascript is included in the html pages. +Google Analytics' JavaScript is included in the HTML pages. -.. code:: python +.. code:: Python html_theme_options["analytics"] = { "google_analytics_id": "G-XXXXXXXXXX", diff --git a/docs/user_guide/announcements.rst b/docs/user_guide/announcements.rst index 9bb23e273..2d71417d9 100644 --- a/docs/user_guide/announcements.rst +++ b/docs/user_guide/announcements.rst @@ -2,7 +2,7 @@ Announcement banners ==================== You can add an announcement banner that draws extra attention from your reader. -It will be displayed at the top of the screen, but will disappear once they start scrolling. +It will be displayed at the top of the screen but will disappear once they start scrolling. To add an announcement banner, use the ``html_theme_options["announcement"]`` configuration. There are two ways to use this. diff --git a/docs/user_guide/branding.rst b/docs/user_guide/branding.rst index a5145e1bb..43402e8b6 100644 --- a/docs/user_guide/branding.rst +++ b/docs/user_guide/branding.rst @@ -5,7 +5,7 @@ Branding and logo Customize logo and title ======================== -By default the theme will use the value of ``project`` on the left side of the header navbar. +By default, the theme will use the value of ``project`` on the left side of the header navigation bar. This can be replaced by a logo image, and optionally a custom ``html_title`` as well. Single logo for light and dark mode @@ -80,24 +80,26 @@ To reference an external website, make sure your link starts with ``http``: Customize logo alternative text ------------------------------- -You may set a custom ``alt text`` to use with your logo to replace the default ("logo image"). -This can make the logo more accessible to those using screen readers or other assistive tech. -To do so, use ``html_teme_options["logo"]["alt_text"]`` as in the following example: +You may set a custom ``alt text`` for your logo to replace the default ``"logo image"`` generic description. +Adding a descriptive ``alt text`` can help make your documentation more accessible to readers using screen readers or another assistive tech. + +To do so, customize the ``html_theme_options["logo"]["alt_text"]`` configuration option as in the following example: .. code-block:: python :caption: conf.py html_theme_options = { "logo": { - "alt_text": "foo", + # Because the logo is also a homepage link, including "home" in the alt text is good practice + "alt_text": "My Project Name - Home", } } Add a logo title ---------------- -To add a title in the brand section of your documentation, define a value for ``html_theme_options.logo["text"]`` -This will appear just after your logo image if it is set. +To add a title in the brand section of your documentation, define a value for ``html_theme_options.logo["text"]``. +This title will appear next to the logo image if set. .. code-block:: python @@ -115,12 +117,13 @@ Add favicons .. deprecated:: 0.15 - Support for complex and multiple favicons will be dropped in version 0.15. Instead use the `sphinx-favicon `__ extension. It provides the same functionality using more flexible parameters. + Support for complex and multiple favicons will be dropped in version 0.15. Instead, use the `sphinx-favicon `__ extension. + It provides the same functionality using more flexible parameters. ``pydata_sphinx_theme`` supports the `standard sphinx favicon configuration `_, using ``html_favicon``. -Additionally you may add any number of browser- or device-specific favicons of any size. +Additionally, you may add any number of browser- or device-specific favicons of any size. To do so, use the ``html_theme_options["favicons"]`` configuration key. The only required argument is ``href``, which can be either an absolute URL (beginning with ``http``) or a local path relative to your ``html_static_path``. In addition, you may specify a size with ``sizes``, specify a ``rel`` value, and specify a ``color``. diff --git a/docs/user_guide/extending.rst b/docs/user_guide/extending.rst index 084790199..1e98f29e3 100644 --- a/docs/user_guide/extending.rst +++ b/docs/user_guide/extending.rst @@ -39,7 +39,7 @@ Then add the ``dropdown`` class to any admonition directive (shown here on a ``n Custom admonition styles ======================== -A `limited set `__ of admonitions are built-in to docutils (the rST → HTML engine that underlies Sphinx). However, it is possible to create custom admonitions with their own default colors, icons, and titles. +A `limited set `__ of admonitions are built-in to docutils (the ``rST`` → ``HTML`` engine that underlies Sphinx). However, it is possible to create custom admonitions with their own default colors, icons, and titles. Customizing the title @@ -69,7 +69,7 @@ The title is specified on the same line as the ``.. admonition::`` directive: Styling with semantic color names --------------------------------- -You can re-style any admonition to match any of the built-in admonition types using any of the semantic color names as a class (this is most useful for custom-titled admonitions): +You can re-style any admonition to match any of the built-in admonition types using any of the :ref:`theme's semantic color names ` as a class (this is most useful for custom-titled admonitions): .. begin-example-semantic .. admonition:: Custom title with "warning" style @@ -78,7 +78,7 @@ You can re-style any admonition to match any of the built-in admonition types us Lorem ipsum dolor sit amet, consectetur adipiscing elit. .. end-example-semantic -Note that it updates both the color and the icon. +Note that it updates both the color and the icon. See :doc:`./styling` for a list of all semantic color names. .. tab-set:: @@ -92,7 +92,6 @@ Note that it updates both the color and the icon. This theme defines classes for `the standard docutils admonition types `__ (``attention``, ``caution``, etc) and additionally supports ``seealso`` and ``todo`` admonitions (see :doc:`../examples/kitchen-sink/admonitions` for a demo of all built-in admonition styles). - Customizing the color --------------------- @@ -105,7 +104,8 @@ Besides the pre-defined semantic color classes (see previous section) you can al Lorem ipsum dolor sit amet, consectetur adipiscing elit. .. end-example-color -Add the new class to your `custom.css `__ file. As in the example below, be sure to use the same color for ``border-color``, ``background-color``, and ``color`` (the transparency effect is handled automatically by the theme). +To do this, you will need to add a class to your `custom.css `__ file, as in the example below. +Be sure to use the same color for ``border-color`` and ``color`` and a different shade for ``background-color``: .. tab-set:: diff --git a/docs/user_guide/fonts.rst b/docs/user_guide/fonts.rst index 0d3564a92..eafb4b323 100644 --- a/docs/user_guide/fonts.rst +++ b/docs/user_guide/fonts.rst @@ -4,14 +4,14 @@ Fonts and FontAwesome The theme includes the `FontAwesome 6 Free `__ icon font (the ``.fa-solid, .fa-regular, .fa-brands`` styles, which are used for :ref:`icon links ` and admonitions). -This is the only *vendored* font, and otherwise the theme by default relies on +This is the only *vendored* font, and otherwise, the theme by default relies on available system fonts for normal body text and headers. The default body and header fonts can be changed as follows: -- Using :ref:`custom-css`, you can specify which fonts to use for body, header - and monospace text. For example, the following can be added to a custom - css file: +- Using :ref:`custom-css`, you can specify which fonts to use for the body, header, + and monospaced text. For example, the following can be added to a custom + CSS file: .. code-block:: css @@ -21,7 +21,7 @@ The default body and header fonts can be changed as follows: --pst-font-family-monospace: Courier, var(--pst-font-family-monospace-system); } - The ``*-system`` variables are available to use as fallback to the default fonts. + The ``*-system`` variables are available to use as a fallback to the default fonts. - If the font you want to specify in the section above is not generally available by default, you will additionally need to ensure the font is loaded. diff --git a/docs/user_guide/header-links.rst b/docs/user_guide/header-links.rst index dfdd36df4..6b410f1ce 100644 --- a/docs/user_guide/header-links.rst +++ b/docs/user_guide/header-links.rst @@ -9,7 +9,7 @@ Navigation Bar External links ============================= You can add external links to your navigation bar. These will show up to the right -of your site's main links, and will have a small icon indicating that they point to +of your site's main links and will have a small icon indicating that they point to an external site. You can add external links to the nav bar like so: .. code:: python @@ -27,10 +27,10 @@ Navigation bar dropdown links By default, this theme will display the first **five** navigation links in the header (including both top-level links and external links). It will place the remaining header links in a **dropdown menu** titled "More". -This prevents the header links from taking up so much space that they crowd out the UI components or spill off screen. +This prevents the header links from taking up so much space that they crowd out the UI components or spill off-screen. To control how many header links are displayed before being placed in the dropdown, use the ``header_links_before_dropdown`` theme configuration variable. -For example, to change the number of displayed header links to be ``4`` instead of ``5``:abbr: +For example, to change the number of displayed header links to be ``4`` instead of ``5``: .. code-block:: python @@ -84,7 +84,7 @@ FontAwesome icons `FontAwesome `_ is a collection of icons that are commonly used in websites. They include both generic shape icons (e.g., "arrow-down"), -as well as brand-specific icons (e.g. "github"). +and brand-specific icons (e.g. "GitHub"). You can use FontAwesome icons by specifying ``"type": "fontawesome"``, and specifying a FontAwesome class in the ``icon`` value. @@ -116,7 +116,7 @@ Here are several examples: "name": "Twitter", "url": "https://twitter.com/", "icon": "fa-brands fa-square-twitter", - # The default for `type` is `fontawesome` so it is not actually required in any of the above examples as it is shown here + # The default for `type` is `fontawesome`, so it is not required in the above examples }, { "name": "Mastodon", @@ -215,7 +215,7 @@ You can add custom attributes to the link element (````) of your icon links. This is helpful if you need to add custom link behavior. To do so, use the pattern ``"attributes": {"attribute1": "value1"}`` in a given icon link entry. -For example, to specify a custom ``target`` and ``rel`` attribute, and to define your own custom link classes: +For example, to specify a custom ``target`` and ``rel`` attribute, and to define your custom link classes: .. code:: python @@ -228,7 +228,7 @@ For example, to specify a custom ``target`` and ``rel`` attribute, and to define "icon": "_static/pydata-logo-square.png", "type": "local", # Add additional attributes to the href link. - # The defaults of target, rel, class, title and href may be overwritten. + # The defaults of the target, rel, class, title, and href may be overwritten. "attributes": { "target" : "_blank", "rel" : "noopener me", @@ -240,4 +240,4 @@ For example, to specify a custom ``target`` and ``rel`` attribute, and to define } .. warning:: - This might make your icon links behave unexpectedly and might over-ride default behavior, so make sure you know what you're doing! + This might make your icon links behave unexpectedly and might override the default behavior, so make sure you know what you're doing! diff --git a/docs/user_guide/indices.rst b/docs/user_guide/indices.rst index bc5be4e01..6bbb9c279 100644 --- a/docs/user_guide/indices.rst +++ b/docs/user_guide/indices.rst @@ -2,7 +2,7 @@ Sphinx indices ============== -Sphinx generates indices named `genindex`, `modindex` and `py-modindex` when building a documentation. More information about them can be found in the Sphinx documentation `here `__. +Sphinx generates indices named `genindex`, `modindex` and `py-modindex` when building a documentation. More information about them can be found in the `Sphinx documentation for indices `__. Add indices links ================= @@ -19,4 +19,4 @@ By design the indices pages are not linked in a documentation generated with thi .. note:: - don't forget to add back the ``"sidebar-ethical-ads.html"`` template if you are serving your documentation using `ReadTheDocs `__. + Don't forget to add back the ``"sidebar-ethical-ads.html"`` template if you are serving your documentation using `ReadTheDocs `__. diff --git a/docs/user_guide/keyboard-shortcuts.md b/docs/user_guide/keyboard-shortcuts.md index fa69b4cbe..c163d47d4 100644 --- a/docs/user_guide/keyboard-shortcuts.md +++ b/docs/user_guide/keyboard-shortcuts.md @@ -2,11 +2,11 @@ ## Trigger the search bar -You can trigger the search bar pop-up with {guilabel}`ctrl`/{guilabel}`cmd` + {guilabel}`K`. +You can trigger the search bar pop-up with {kbd}`Ctrl`/{kbd}`⌘` + {kbd}`K`. ## Change pages -By default, you can move to the previous/next page using the {octicon}`arrow-left` and {octicon}`arrow-right` keys on a keyboard. +By default, you can move to the previous/next page using the {octicon}`arrow-left` (left arrow) and {octicon}`arrow-right` (right arrow) keys on a keyboard. To disable this behavior, use the following configuration: ```py @@ -14,3 +14,7 @@ html_theme_options = { "navigation_with_keys": False } ``` + +```{attention} +Keep in mind that many readers use their keyboards and other assistive technology to interact with web documents. If you disable the keyboard navigation, you might be making your documentaion inaccessible to many readers. +``` diff --git a/docs/user_guide/layout.rst b/docs/user_guide/layout.rst index 3dc19c983..018f32679 100644 --- a/docs/user_guide/layout.rst +++ b/docs/user_guide/layout.rst @@ -11,7 +11,7 @@ Overview of theme layout Below is a brief overview of the major layout of this theme. Take a look at the diagram to understand what the major sections are called. Where you can insert component templates in ``html_theme_options``, we include the variable name ``in inline code``. -Click on section titles to learn more about them and some basic layout configuration. +Click on section titles to learn more about them and some basic layout configurations. .. The directives below generate a grid-like layout that mimics the structure of this theme. .. It uses Sphinx Design grids: https://sphinx-design.readthedocs.io/en/latest/grids.html @@ -174,7 +174,7 @@ Click on section titles to learn more about them and some basic layout configura Horizontal spacing ------------------ -By default the theme's three columns have fixed widths. +By default, the theme's three columns have fixed widths. The ``primary sidebar`` will snap to the left, the ``secondary sidebar`` will snap to the right, and the ``article content`` will be centered in between. - If one of the sidebars is not present, then the ``article content`` will be centered between the other sidebar and the side of the page. @@ -212,8 +212,8 @@ Templates and components ======================== There are a few major theme sections that you can customize to add/remove -components, or add your own components. Each section is configured with a -list of *html templates* — these are snippets of HTML that are inserted into +built-in components or add your own components. Each section is configured with a +list of *HTML templates* — these are snippets of HTML that are inserted into the section by Sphinx. You can choose which templates show up in each section, as well as the order in @@ -232,7 +232,7 @@ Header / Navigation Bar Located in ``sections/header.html``. -The header is at the top of the page above all other content, and contains site-level information. +The header is at the top of the page above all other content and contains site-level information. Header sections --------------- @@ -260,7 +260,7 @@ By default, the following configuration is used: .. warning:: - The *Persistent right section* is placed next to the ``navbar_end`` but its elements will remain visible in the header even on small screens when all other elements are collapsed. It has been design for the ``search-button`` only and we cannot guarantee its compatibility with other components. + The *Persistent right section* is placed next to the ``navbar_end``, but its elements will remain visible in the header even on small screens when all other elements are collapsed. It has been design for the ``search-button`` only and we cannot guarantee its compatibility with other components. Configure the navbar center alignment ------------------------------------- @@ -276,7 +276,7 @@ page. This equals the following default configuration: # ... } -If instead you'd like these items to snap to the left (closer to the logo), use this +If instead, you'd like these items to snap to the left (closer to the logo), use this configuration: .. code-block:: python @@ -322,9 +322,9 @@ Located in ``sections/sidebar-primary.html``. The primary sidebar is just to the left of a page's main content. It is primarily used for between-section navigation. -By default it will show links to any sublings / children of the current active top-level section (corresponding to links in your header navigation bar). +By default, it will show links to any siblings/children of the current active top-level section (corresponding to links in your header navigation bar). -Configuring it is a bit different from configuring the other sections, because configuring the sidebar is natively supported in Sphinx, via the ``html_sidebars`` configuration variable. +Configuring it is a bit different from configuring the other sections because configuring the sidebar is natively supported in Sphinx, via the ``html_sidebars`` configuration variable. For the primary sidebar only, you can configure templates so that they only show up on certain pages. You do so via a configuration like so in ``conf.py``: @@ -408,8 +408,8 @@ Footer Content Located in ``sections/footer-content.html``. -The footer content is a narrow bar spanning the article’s content and secondary sidebar. -It does not contain anything immediately viewable to the reader, but is kept as a placeholder in case theme developers wish to re-use it in the future. +The footer content is a narrow bar spanning the article's content and the secondary sidebar. +It does not contain anything immediately viewable to the reader but is kept as a placeholder in case theme developers wish to re-use it in the future. .. _layout-sidebar-secondary: @@ -419,7 +419,7 @@ Secondary Sidebar (right) Located in ``sections/sidebar-secondary.html``. -The in-page sidebar is just to the right of a page's article content, and is +The in-page sidebar is just to the right of a page's article content and is configured in ``conf.py`` with ``html_theme_options['secondary_sidebar_items']``. By default, it has the following templates: @@ -487,7 +487,7 @@ Footer Located in ``sections/footer.html``. -The footer is just below a page’s main content, and is configured in ``conf.py`` +The footer is just below a page's main content, and is configured in ``conf.py`` with ``html_theme_options['footer_start']`` and ``html_theme_options['footer_end']``. By default, ``footer_end`` is empty, and ``footer_start`` has the following templates: diff --git a/docs/user_guide/light-dark.rst b/docs/user_guide/light-dark.rst index 6ca1aa7c0..bfb6ea88f 100644 --- a/docs/user_guide/light-dark.rst +++ b/docs/user_guide/light-dark.rst @@ -4,7 +4,7 @@ Light and dark themes ===================== -You can change the major background / foreground colors of this theme according to "dark" and "light" modes. +You can change the major background/foreground colors of this theme using built-in "dark" and "light" modes. These are controlled by a button in the navigation header, with the following options: - A ``light`` theme with a bright background and dark text / UI elements @@ -47,7 +47,7 @@ Customize the CSS of light and dark themes .. danger:: - Theming is still a beta feature so the variables related to color theming are likely to change in the future. No backward compatibility is guaranteed when customization is done. + Theming is still a beta feature, so the variables related to color theming are likely to change in the future. No backward compatibility is guaranteed when customization is done. To customize the CSS of page elements in a theme-dependent manner, use the ``html[data-theme='']`` CSS selector. @@ -74,8 +74,8 @@ A complete list of the colors used in this theme can be found in the :doc:`CSS s Theme-dependent images and content ---------------------------------- -It is possible to use different content for light and dark mode, so that the content only shows up when a particular theme is active. -This is useful if your content depends on the theme's style, such as a PNG image with a light or a dark background. +It is possible to use different content for light and dark modes so that the content only shows up when a particular theme is active. +This is useful if your content depends on the theme's style, such as a PNG image with a light or dark background. There are **two CSS helper classes** to specify items on the page as theme-specific. These are: @@ -109,7 +109,7 @@ visible, and their brightness will be reduced by a filter. If your image is suitable for the dark theme, add the CSS class :code:`only-dark` as noted above. If your image is suitable for both light and -dark theme, add the CSS class :code:`dark-light` to make your image +dark themes, add the CSS class :code:`dark-light` to make your image theme-agnostic. For example, here's an image without adding this helper class. diff --git a/docs/user_guide/navigation.rst b/docs/user_guide/navigation.rst index be8b03aa6..ee59cb424 100644 --- a/docs/user_guide/navigation.rst +++ b/docs/user_guide/navigation.rst @@ -3,7 +3,7 @@ Navigation depth and collapsing sidebars ======================================== -By default, this theme enables to expand/collapse subsections in the primary +By default, this theme allows expanding/collapsing subsections in the primary sidebar navigation (without actually navigating to the page itself), and this extends up to 4 levels deep: @@ -24,10 +24,10 @@ default, you can use the following configuration in ``conf.py``: "show_nav_level": 2 } -This will make the first two navigations show up by default (AKA, top-level +This will make the first two navigation levels show up by default (AKA, top-level pages and their immediate children). -Collapse entire toctree captions / parts +Collapse entire toctree captions/parts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If your ``toctree`` elements have captions assigned to them (with ``:caption:``), you may @@ -43,7 +43,7 @@ To enable this behavior, set the ``show_nav_level`` value to 0, like below: } You can only collapse your ``toctree`` items underneath their caption if a caption is defined for them! -If your ``toctree`` does not have a caption defined, then all of the pages underneath it will be displayed +If your ``toctree`` does not have a caption defined, then all the pages underneath it will be displayed (the same as the default theme behavior). See `the toctree documentation `_ for more details. diff --git a/docs/user_guide/page-toc.rst b/docs/user_guide/page-toc.rst index 5c3c77f1a..60a3a423a 100644 --- a/docs/user_guide/page-toc.rst +++ b/docs/user_guide/page-toc.rst @@ -4,8 +4,8 @@ Page Table of Contents Show more levels of the in-page TOC by default ---------------------------------------------- -Normally only the 2nd-level headers of a page are show in the right -table of contents, and deeper levels are only shown when they are part +Normally only the 2nd-level headers of a page are shown in the right +table of contents and deeper levels are only shown when they are part of an active section (when it is scrolled on screen). You can show deeper levels by default by using the following configuration, indicating how many levels should be displayed: diff --git a/docs/user_guide/search.rst b/docs/user_guide/search.rst index 9a0faf13c..ecab78254 100644 --- a/docs/user_guide/search.rst +++ b/docs/user_guide/search.rst @@ -15,9 +15,9 @@ Configure the search field position ----------------------------------- The position of the search *button* is controlled by ``search-button`` and by default is included in ``html_theme_options["navbar_persistent"]``; you may move it elsewhere as befits your site's layout, or remove it. -You can also add an always-visible search field to some/all pages in your site by adding ``search-field.html`` to one of the configuration variables (e.g., ``html_sidebars``, ``html_theme_options["footer_start"]``, etc). +You can also add an always-visible search field to some/all pages in your site by adding ``search-field.html`` to one of the configuration variables (e.g., ``html_sidebars``, ``html_theme_options["footer_start"]``, etc.). -For example, if you'd like the search field to be in your side-bar, add it to +For example, if you'd like the search field to be in your sidebar, add it to the sidebar templates like so: .. code:: python @@ -26,7 +26,7 @@ the sidebar templates like so: "**": ["search-field.html", "sidebar-nav-bs.html", "sidebar-ethical-ads.html"] } -If instead you'd like to put the search field in the top navbar, use the +If instead, you'd like to put the search field in the top navbar, use the following configuration: .. code:: python @@ -37,7 +37,7 @@ following configuration: .. warning:: - If a page includes *both* the search button and an always-visible search field, the keyboard shortcuts will focus the always-visible field and the hidden search field overlay will not display. *This may not be what you want:* on small screens (i.e. mobile devices) the sidebars may be hidden in a drawer, and if the persistent search field is there, it may receive focus without actually being made visible. It is **strongly recommended** that you use *either* search button and the hidden/overlaid field that comes with it, *or* use a persistent search field in a place that makes sense for your layout. + If a page includes *both* the search button and an always-visible search field, the keyboard shortcuts will focus on the always-visible field and the hidden search field overlay will not display. *This may not be what you want:* on small screens (i.e. mobile devices) the sidebars may be hidden in a drawer, and if the persistent search field is there, it may receive focus without actually being made visible. It is **strongly recommended** that you use *either* the search button and the hidden/overlaid field that comes with it, *or* use a persistent search field in a place that makes sense for your layout. Configure the search bar text diff --git a/docs/user_guide/static_assets.md b/docs/user_guide/static_assets.md index 8452a4eb5..2611bd27e 100644 --- a/docs/user_guide/static_assets.md +++ b/docs/user_guide/static_assets.md @@ -19,11 +19,11 @@ mysphinxsite/ Any folders that are listed in `html_static_path` will be treated as containing static assets for your build. All files within these folders will be copied to your build's `_static` folder at build time. -For example, with an `html` builder, files will be copied to `_build/html/_static`. +For example, with an HTML builder, files will be copied to `_build/html/_static`. These files are _flattened_ when they are copied, so any folder hierarchies will be lost. -Listing folders with your static assets must be done before any of the methods describe below. +Listing folders with your static assets must be done before any of the methods described below. When you define asset names in the methods described below, they generally assume paths that are _relative to this `_static` output folder_. ## Define a list of assets in `conf.py` @@ -44,9 +44,9 @@ html_js_files = ["myjs.js"] This will cause each to be linked in your ``. -## Add assets in your setup function +## Add assets to your setup function -Additionally you may add assets manually, to do so, use the `app` object in [the Sphinx `setup()` function](https://www.sphinx-doc.org/en/master/extdev/appapi.html#extension-setup). +Additionally, you may add assets manually, to do so, use the `app` object in [the Sphinx `setup()` function](https://www.sphinx-doc.org/en/master/extdev/appapi.html#extension-setup). The `app` object has two relevant methods here: [**`app.add_css_file`**](https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_css_file) allows you to add CSS files directly. @@ -77,7 +77,7 @@ def setup(app): ## Use an event to add it to specific pages -If you'd like to use logic to only add a script to certain pages, or to trigger different behavior depending on the page, use [a Sphinx event hook](https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events). +If you'd like to use logic to only add a script to certain pages or to trigger different behavior depending on the page, use [a Sphinx event hook](https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events). This involves defining a function that runs when a particular event is emitted in the Sphinx build, and using [`app.connect()`](https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.connect) to connect it to your build. The event you'll likely want to use is [`html-page-context`](https://www.sphinx-doc.org/en/master/extdev/appapi.html#event-html-page-context). @@ -120,7 +120,7 @@ If you're using reStructuredText or MyST Markdown, you can use the `raw` directi ``` -If you're using MyST Markdown, you may also simply directly include any HTML / style / script blocks in your content without using a directive. +If you're using MyST Markdown, you may also directly include any HTML / style / script blocks in your content without using a directive. For example: diff --git a/docs/user_guide/styling.rst b/docs/user_guide/styling.rst index 4435902bf..3e2df90a2 100644 --- a/docs/user_guide/styling.rst +++ b/docs/user_guide/styling.rst @@ -12,18 +12,18 @@ This section covers a few ways that you can control the look and feel of your th Custom CSS Stylesheets ====================== -You may customize the theme's CSS by creating a custom stylesheet that Sphinx uses to build your site. -Any rules in this style-sheet will over-ride the default theme rules. +You can customize the theme's CSS by creating a custom stylesheet. This stylesheet will be used by Sphinx while building your site. +Any rules in this style sheet will override the default theme rules. .. seealso:: - For a more in-depth guide in linking static CSS and JS assets in your site, see {doc}`static_assets`. + For a more in-depth guide in linking static CSS and JS assets in your site, see :doc:`static_assets`. To add a custom stylesheet, follow these steps: -1. **Create a CSS stylesheet** in ``_static/css/custom.css``, and add the CSS rules you wish. -2. **Attach the stylesheet to your Sphinx build**. Add the following to ``conf.py`` +1. **Create a CSS stylesheet** in ``_static/css/custom.css``, and update the CSS rules as desired. +2. **Attach the stylesheet to your Sphinx build**. Add the following to ``conf.py``: .. code-block:: python @@ -42,16 +42,15 @@ This theme defines several `CSS variables `_ that can be used to quickly control behavior and display across your documentation. These are based on top of the basic `Bootstrap CSS variables `_ -extended with some theme specific variables. +extended with some theme-specific variables. -base variables +Base variables -------------- -In order to change a variable, follow these steps: +Follow these steps to update the base variables: 1. :ref:`Add a custom CSS stylesheet `. This is where we'll configure the variables. -2. Underneath a ``html`` section, add the variables you wish to update. For example, to update - the base font size, you might add this to ``custom.css``: +2. Underneath a ``html`` section, add the variables you wish to update. For example, to change the base font size you would add the following to your ``custom.css`` file : .. code-block:: css @@ -61,9 +60,10 @@ In order to change a variable, follow these steps: .. important:: - Note that these are `CSS variables `_ and not - `SASS variables `_. - The theme is defined with CSS variables, not SASS variables! Refer to the previous section if + Note that the theme is defined with `CSS variables `_ + and **not** `SASS variables `_. + + Refer to :ref:`the managing themes section in this documentation ` if you desire a different behavior between the light and dark theme. For a complete list of the theme variables that you may override, see the @@ -84,24 +84,27 @@ For a complete list of the theme variables that you may override, see the .. literalinclude:: ../../src/pydata_sphinx_theme/assets/styles/variables/_versionmodified.scss :language: scss +.. _color-variables: + Color variables --------------- -There are two special color variables for primary and secondary theme colors (``--pst-color-primary`` and ``--pst-color-secondary``, respectively). +This theme specifies color variables for the primary and secondary colors (``--pst-color-primary`` and ``--pst-color-secondary``, respectively). These are meant to complement one another visually across the theme, if you modify these, choose colors that look good when paired with one another. -There are also several other color variables that control color for admonitions, links, menu items, etc. +There are also several other color variables that control the color for admonitions, links, menu items, etc. Each color variable has two values, one corresponding to the "light" and one for the "dark" theme. These are used throughout many of the theme elements to define text color, background color, etc. Here is an overview of the colors available in the theme (change theme mode to switch from light to dark versions). + .. raw:: html

- primary - secondary - success - info - warning - danger + primary + secondary + accent + success + info + warning + danger background on-background surface - on-surface + on-surface target

@@ -145,7 +149,7 @@ It defines 4 color variables that help build overlays in your documentation. - :code:`background`: color of the back-most surface of the documentation - :code:`on-background` elements that are set on top of this background (e.g. the header navbar on dark mode). -- :code:`surface` elements set on the background with a light-grey color in the light theme mode. this color has been kept in the dark theme (e.g. code-block directives). +- :code:`surface` elements set on the background with a light-grey color in the light theme mode. This color has been kept in the dark theme (e.g. code-block directives). - :code:`on-surface` elements that are on top of :code:`surface` elements (e.g. sidebar directives). The following image should help you understand these overlays: @@ -174,7 +178,7 @@ The following image should help you understand these overlays:

surface

-

on-surface

+

on-surface

@@ -189,7 +193,8 @@ For a complete list of the theme colors that you may override, see the :download Configure pygments theme ======================== -As the Sphinx theme supports multiple modes, the code highlighting colors can be modified for each one of them by modifying the ``pygment_light_style`` and ``pygment_dark_style``. You can check available Pygments colors on this `page `__. +As the Sphinx theme supports multiple modes, the code highlighting colors can be modified for each one of them by modifying the ``pygment_light_style`` and ``pygment_dark_style``. +You can check available Pygments colors on this `pygments demo page `__. .. code-block:: python @@ -199,6 +204,11 @@ As the Sphinx theme supports multiple modes, the code highlighting colors can be "pygment_dark_style": "monokai" } +Note that the PyData Sphinx theme uses the `accessible pygments styles `__ for its default syntax highlighting themes. +The accessible pygments themes are designed to meet `WCAG AA or AAA standards for color contrast `__ and some included themes are also suitable for colorblind users +or low-light conditions. +You can check all the available styles at the `accessible pygments demo page `__. + .. danger:: The native Sphinx option ``pygments_style`` will be overwritten by this theme. diff --git a/docs/user_guide/theme-elements.md b/docs/user_guide/theme-elements.md index ed43afaea..58d9cff68 100644 --- a/docs/user_guide/theme-elements.md +++ b/docs/user_guide/theme-elements.md @@ -1,7 +1,7 @@ # Theme-specific elements There are a few elements that are unique or particularly important to this theme. -Some of these are triggered with configuration or markdown syntax that is unique to the theme, and we cover them below. +Some of these are triggered with configuration or Markdown syntax that is unique to the theme, and we cover them below. ```{contents} Page contents :local: @@ -9,11 +9,10 @@ Some of these are triggered with configuration or markdown syntax that is unique ## Mathematics -Most Sphinx sites support math, but it is particularly important for scientific computing and so we illustrate support here as well. +Most Sphinx sites support math, but it is particularly important for scientific computing, so we illustrate support here as well. Here is an inline equation: {math}`X_{0:5} = (X_0, X_1, X_2, X_3, X_4)` and {math}`another` and {math}`x^2 x^3 x^4` another. And here's one to test vertical height {math}`\frac{\partial^2 f}{\partial \phi^2}`. - -Here is block-level equation: +Here is a block-level equation: ```{math} :label: My label @@ -45,7 +44,7 @@ And here is a really long equation with a label! \frac{1}{r^2 \sin^2\theta} \frac{\partial^2 f}{\partial \phi^2} ``` -You can add a link to equations like the one above: {eq}`My label` and {eq}`My label 2`. +You can add a link to equations like the one above {eq}`My label` and {eq}`My label 2`. ## Code blocks @@ -58,7 +57,7 @@ print("A regular code block") print("A regular code block") ``` -You can also provide captions with code blocks, which will be displayed just above the code. +You can also provide captions with code blocks, which will be displayed right above the code. For example, the following code: ````md @@ -104,7 +103,7 @@ print("A code block with a caption and line numbers.") ## Inline code -When used directly, the `code` role just displays the text without syntax highlighting, as a literal. As mentioned in the [Sphinx documentation](https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#inline-code-highlighting) you can also enable syntax highlighting by defining a custom role. It will then use the same highligther as in the `code-block` directive. +When used directly, the `code` role just displays the text without syntax highlighting, as a literal. As mentioned in the [Sphinx documentation](https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#inline-code-highlighting) you can also enable syntax highlighting by defining a custom role. It will then use the same highlighter as in the `code-block` directive. ```{code-block} rst @@ -147,13 +146,13 @@ Here's one footnote[^1] and another footnote [^2] and a named footenote[^named], ## Version changes -This theme supports a short-hand way of making **admonitions behave like sidebars**. +This theme supports a shorthand way of making **admonitions behave like sidebars**. This can be a helpful way of highlighting content that lives to the side of your main text without interrupting the vertical flow as much. For example, look to the right of an "admonition sidebar" and a traditional Sphinx sidebar. To make an admonition behave like a sidebar, add the `sidebar` class to its list of classes. -For example, the admonition sidebar was created with the following markdown: +For example, the admonition sidebar was created with the following Markdown: ````md ```{admonition} A sidebar admonition! @@ -169,7 +168,7 @@ Instead of displaying these as raw links, this theme does some lightweight forma In **reStructuredText**, URLs are automatically converted to links, so this works automatically. -In **MyST Markdown**, by default you must define a standard markdown link and duplicate the URL in the link text. +In **MyST Markdown**, by default, you must define a standard Markdown link and duplicate the URL in the link text. You may skip the need to manually define the link text by [activating the MyST Linkify extension](https://myst-parser.readthedocs.io/en/latest/syntax/optional.html#linkify). For example: diff --git a/docs/user_guide/version-dropdown.rst b/docs/user_guide/version-dropdown.rst index 8a9b17cef..2502a99c4 100644 --- a/docs/user_guide/version-dropdown.rst +++ b/docs/user_guide/version-dropdown.rst @@ -7,7 +7,7 @@ switcher will differ depending on which page of the docs is being viewed. For example, on the page ``https://mysite.org/en/v2.0/changelog.html``, the switcher links will go to ``changelog.html`` in the other versions of your docs. When clicked, the switcher will check for the existence of that page, and -if it doesn't exist, redirect to the homepage of that docs version instead. +if it doesn't exist, will redirect to the homepage instead (in the requested version of the docs). The switcher requires the following configuration steps: @@ -23,7 +23,7 @@ The switcher requires the following configuration steps: 3. Specify where to place the switcher in your page layout. For example, add the ``"version-switcher"`` template to one of the layout lists in - ``html_theme_options`` (e.g., ``navbar_end``, ``footer_start``, etc). + ``html_theme_options`` (e.g., ``navbar_end``, ``footer_start``, etc.). Below is a more in-depth description of each of these configuration steps. @@ -39,7 +39,7 @@ each can have the following fields: ``switcher['version_match']`` to provide styling to the switcher. - ``url``: the URL for this version. - ``name``: an optional name to display in the switcher dropdown instead of the - version string (e.g., "latest", "stable", "dev", etc). + version string (e.g., "latest", "stable", "dev", etc.). Here is an example JSON file: @@ -77,7 +77,7 @@ not specified as a path relative to the sphinx root of the current doc build). Each version of your documentation should point to the same URL, so that as new versions are added to the JSON file all the older versions of the docs will gain switcher dropdown entries linking to the new versions. This could be done -a few different ways: +in a few different ways: - The location could be one that is always associated with the most recent documentation build (i.e., if your docs server aliases "latest" to the most @@ -93,7 +93,7 @@ a few different ways: } } - In this case the JSON is versioned alongside the rest of the docs pages but + In this case, the JSON is versioned alongside the rest of the docs pages but only the most recent version is ever loaded (even by older versions of the docs). @@ -115,7 +115,7 @@ a few different ways: } } -By default the theme is testing the :code:`.json` file provided and outputs warnings in the Sphinx build. If this test breaks the pipeline of your docs, the test can be disabled by configuring the :code:`check_switcher` parameter in :code:`conf.py`: +By default, the theme is testing the :code:`.json` file provided and outputs warnings in the Sphinx build. If this test breaks the pipeline of your docs, the test can be disabled by configuring the :code:`check_switcher` parameter in :code:`conf.py`: .. code-block:: python @@ -132,7 +132,7 @@ being viewed, and is used to style the switcher (i.e., to highlight the current docs version in the switcher's dropdown menu, and to change the text displayed on the switcher button). -Typically you can re-use one of the sphinx variables ``version`` +Typically, you can re-use one of the sphinx variables ``version`` or ``release`` as the value of ``switcher['version_match']``; which one you use depends on how granular your docs versioning is. See `the Sphinx "project info" documentation @@ -229,4 +229,4 @@ version, you could use the following CSS selector: .. seealso:: See the `MDN documentation on dataset properties `_ - for more information on using and styling with these properties. + for more information on using and styling these properties. diff --git a/docs/user_guide/web-components.rst b/docs/user_guide/web-components.rst index d01f8dca9..54bae0db5 100644 --- a/docs/user_guide/web-components.rst +++ b/docs/user_guide/web-components.rst @@ -4,11 +4,14 @@ Sphinx Design Components ======================== -Cards and tabs provide some extra UI flexibility for your content. This theme provides custom CSS to ensure that `sphinx-design `__ elements look and feel consistent with this theme. +The PyData Sphinx Theme uses `sphinx-design `__ +to add several UI components and provide extra flexibility for content creation. +These include badges, buttons, cards, and tabs, among other components. +This theme provides custom CSS to ensure that `sphinx-design `__ elements look and feel consistent with this theme. .. seealso:: - For more about how to use these extensions, see `the sphinx-design documentation `_. + For more information about how to use these extensions, see `the sphinx-design documentation `_. Below you can find some examples of the components created with the :code:`sphinx-design` extension. @@ -18,6 +21,7 @@ Badges and buttons ================== Here are some of the available badges: + :bdg-primary:`primary` :bdg-secondary:`secondary` :bdg-success:`success` @@ -25,8 +29,7 @@ Here are some of the available badges: :bdg-secondary-line:`secondary outline` :bdg-success-line:`success outline` -Here are some buttons, also using semantic color names. **Note:** in this theme, ``info`` is defined to be the same color as ``primary``, and ``warning`` is the same color as ``secondary``. -If in your site's `custom CSS file `_ you override the `CSS custom properties `_ ``--pst-color-*`` (where ``*`` is one of the semantic color names, e.g., ``primary``, ``danger``, etc), badges and buttons will automatically use the custom color. +Here are some of the available buttons, also using semantic colors: .. grid:: auto @@ -39,6 +42,15 @@ If in your site's `custom CSS file `_ you override the `CSS custom p Info + .. grid-item:: + + .. button-ref:: badges-buttons + :ref-type: ref + :color: success + :shadow: + + Success + .. grid-item:: .. button-ref:: badges-buttons @@ -66,6 +78,26 @@ If in your site's `custom CSS file `_ you override the `CSS custom p Muted + .. grid-item:: + + .. button-ref:: badges-buttons + :ref-type: ref + :color: light + :shadow: + + Light + + .. grid-item:: + + .. button-ref:: badges-buttons + :ref-type: ref + :color: dark + :shadow: + + Dark + +If in your site's `custom CSS file `_ you override the `CSS custom properties `_ ``--pst-color-*`` (where ``*`` is one of the semantic color names, such as ``primary``, ``danger``), badges and buttons will automatically use the custom color. + Cards ===== @@ -83,13 +115,13 @@ Cards Content of the third card. - :bdg-primary:`example` + :bdg-primary:`Sample badge` .. grid:: .. grid-item-card:: A card with a dropdown menu - .. dropdown:: :fa:`eye me-1` third card + .. dropdown:: :fa:`eye me-1` Click to expand dropdown Hidden content @@ -115,7 +147,6 @@ Cards ++++++++++++++ panel 2 footer - Tabs ==== @@ -162,7 +193,7 @@ Tabs Dropdowns ========= -Dropdowns should look similar to admonitions, but clickable. +Dropdowns look similar to admonitions, but they are clickable interactive elements that can be used to hide content. See `the Sphinx Design Dropdown documentation `__ for more information. .. admonition:: An admonition for reference. @@ -177,18 +208,18 @@ See `the Sphinx Design Dropdown documentation = $min-contrast-ratio { + @return $fg; + } @else if $contrast-ratio > $max-ratio { + $max-ratio: $contrast-ratio; + $max-ratio-color: $fg; + } + } + @warn "Found no color leading to #{$min-contrast-ratio}:1 contrast ratio against #{$bg}..."; + + @return $max-ratio-color; +} + +@function get-contrast-ratio($bg, $foreground) { + $l1: luminance($bg); + $l2: luminance($foreground); + + // return the relative contrast ratio + @if $l1 > $l2 { + @return math.div(($l1 + 0.05), ($l2 + 0.05)); + } @else { + @return math.div(($l2 + 0.05), ($l1 + 0.05)); + } +} + +// Return WCAG2.1 relative luminance +// See https://www.w3.org/TR/WCAG/#dfn-relative-luminance +// See https://www.w3.org/TR/WCAG/#dfn-contrast-ratio + +@function luminance($target-color) { + $rgb-col: ( + "r": red($target-color), + "g": green($target-color), + "b": blue($target-color), + ); + + @each $channel, $value in $rgb-col { + // here we get RsRGB, GsRGB, and BsRGB + @if math.div($value, 255) <=0.03928 { + $rgb-col: map-merge( + $rgb-col, + ( + $channel: math.div(math.div($value, 255), 12.92), + ) + ); + } @else { + $rgb-col: map-merge( + $rgb-col, + ( + $channel: + math.pow(math.div((math.div($value, 255) + 0.055), 1.055), 2.4), + ) + ); + } + } + + @return ( + 0.2126 * map-get($rgb-col, "r") + 0.7152 * map-get($rgb-col, "g") + 0.0722 * + map-get($rgb-col, "b") + ); +} diff --git a/src/pydata_sphinx_theme/assets/styles/base/_base.scss b/src/pydata_sphinx_theme/assets/styles/base/_base.scss index 7c18e23fd..9970ec12e 100644 --- a/src/pydata_sphinx_theme/assets/styles/base/_base.scss +++ b/src/pydata_sphinx_theme/assets/styles/base/_base.scss @@ -47,8 +47,8 @@ a { } &.headerlink { - color: var(--pst-color-warning); - opacity: 0.4; + color: var(--pst-color-secondary); + opacity: 0.7; font-size: 0.8em; padding: 0 4px 0 4px; margin-left: 0.2em; @@ -91,25 +91,25 @@ h1 { @extend .heading-style; margin-top: 0; font-size: var(--pst-font-size-h1); - color: var(--pst-color-primary); + color: var(--pst-heading-color); } h2 { @extend .heading-style; font-size: var(--pst-font-size-h2); - color: var(--pst-color-primary); + color: var(--pst-heading-color); } h3 { @extend .heading-style; font-size: var(--pst-font-size-h3); - color: var(--pst-color-text-base); + color: var(--pst-heading-color); } h4 { @extend .heading-style; font-size: var(--pst-font-size-h4); - color: var(--pst-color-text-base); + color: var(--pst-heading-color); } h5 { @@ -169,7 +169,8 @@ pre { border-radius: $admonition-border-radius; .linenos { - opacity: 0.5; + // minimum opacity to make the line numbers WCAG AA conformant + opacity: 0.8; padding-right: 10px; } } diff --git a/src/pydata_sphinx_theme/assets/styles/components/_searchbox.scss b/src/pydata_sphinx_theme/assets/styles/components/_searchbox.scss index 8eb94d45f..fd875c54e 100644 --- a/src/pydata_sphinx_theme/assets/styles/components/_searchbox.scss +++ b/src/pydata_sphinx_theme/assets/styles/components/_searchbox.scss @@ -24,8 +24,7 @@ div#searchbox { font-size: 1.25rem; padding: 0.75rem; background-color: var(--pst-color-primary); - // Button text is always white with Sphinx Design buttons - color: white; + color: var(--pst-color-primary-text); // The box shadow is inset so that it darkens the button on hover transition: box-shadow 0.25s ease-out; diff --git a/src/pydata_sphinx_theme/assets/styles/components/_toc-inpage.scss b/src/pydata_sphinx_theme/assets/styles/components/_toc-inpage.scss index 2f2fc76ca..f26eb92f4 100644 --- a/src/pydata_sphinx_theme/assets/styles/components/_toc-inpage.scss +++ b/src/pydata_sphinx_theme/assets/styles/components/_toc-inpage.scss @@ -25,6 +25,9 @@ nav.page-toc { // Each entry of the in-page TOC .toc-entry { display: block; + a > code { + color: var(--pst-color-text-muted); + } a.nav-link { display: block; diff --git a/src/pydata_sphinx_theme/assets/styles/components/_versionmodified.scss b/src/pydata_sphinx_theme/assets/styles/components/_versionmodified.scss index 2ed777a02..c0174633b 100644 --- a/src/pydata_sphinx_theme/assets/styles/components/_versionmodified.scss +++ b/src/pydata_sphinx_theme/assets/styles/components/_versionmodified.scss @@ -17,33 +17,22 @@ div.deprecated { > p { margin-bottom: 0.6rem; margin-top: 0.6rem; - - @include background-from-color-variable(--pst-color-info); } } div.versionadded { border-color: var(--pst-color-success); - - p:before { - background-color: var(--pst-color-success); - } + background-color: var(--pst-color-success-bg); } div.versionchanged { border-color: var(--pst-color-warning); - - p:before { - background-color: var(--pst-color-warning); - } + background-color: var(--pst-color-warning-bg); } div.deprecated { border-color: var(--pst-color-danger); - - p:before { - background-color: var(--pst-color-danger); - } + background-color: var(--pst-color-danger-bg); } span.versionmodified { diff --git a/src/pydata_sphinx_theme/assets/styles/content/_admonitions.scss b/src/pydata_sphinx_theme/assets/styles/content/_admonitions.scss index 29bc84cbe..a71490580 100644 --- a/src/pydata_sphinx_theme/assets/styles/content/_admonitions.scss +++ b/src/pydata_sphinx_theme/assets/styles/content/_admonitions.scss @@ -38,6 +38,9 @@ div.admonition, padding: 0.4rem 0.6rem 0.4rem 2rem; font-weight: var(--pst-admonition-font-weight-heading); position: relative; + @include background-from-color-variable(--pst-color-info-bg); + // now that we use solid colors we want the title on top + z-index: 1; &:after { position: absolute; @@ -51,8 +54,6 @@ div.admonition, opacity: 1; } - @include background-from-color-variable(--pst-color-info); - // Next element after title needs some extra upper-space + * { margin-top: 0.4em; @@ -63,7 +64,7 @@ div.admonition, border-color: var(--pst-color-attention); > .admonition-title { &:before { - background-color: var(--pst-color-attention); + background-color: var(--pst-color-attention-bg); } &:after { @@ -77,7 +78,7 @@ div.admonition, border-color: var(--pst-color-warning); > .admonition-title { &:before { - background-color: var(--pst-color-warning); + background-color: var(--pst-color-warning-bg); } &:after { @@ -91,7 +92,7 @@ div.admonition, border-color: var(--pst-color-warning); > .admonition-title { &:before { - background-color: var(--pst-color-warning); + background-color: var(--pst-color-warning-bg); } &:after { @@ -105,7 +106,7 @@ div.admonition, border-color: var(--pst-color-danger); > .admonition-title { &:before { - background-color: var(--pst-color-danger); + background-color: var(--pst-color-danger-bg); } &:after { @@ -119,7 +120,7 @@ div.admonition, border-color: var(--pst-color-danger); > .admonition-title { &:before { - background-color: var(--pst-color-danger); + background-color: var(--pst-color-danger-bg); } &:after { @@ -133,7 +134,7 @@ div.admonition, border-color: var(--pst-color-success); > .admonition-title { &:before { - background-color: var(--pst-color-success); + background-color: var(--pst-color-success-bg); } &:after { @@ -147,7 +148,7 @@ div.admonition, border-color: var(--pst-color-success); > .admonition-title { &:before { - background-color: var(--pst-color-success); + background-color: var(--pst-color-success-bg); } &:after { @@ -161,7 +162,7 @@ div.admonition, border-color: var(--pst-color-attention); > .admonition-title { &:before { - background-color: var(--pst-color-attention); + background-color: var(--pst-color-attention-bg); } &:after { @@ -175,7 +176,7 @@ div.admonition, border-color: var(--pst-color-info); > .admonition-title { &:before { - background-color: var(--pst-color-info); + background-color: var(--pst-color-info-bg); } &:after { @@ -189,7 +190,7 @@ div.admonition, border-color: var(--pst-color-success); > .admonition-title { &:before { - background-color: var(--pst-color-success); + background-color: var(--pst-color-success-bg); } &:after { @@ -200,14 +201,14 @@ div.admonition, } &.admonition-todo { - border-color: var(--pst-color-border); + border-color: var(--pst-color-secondary); > .admonition-title { &:before { - background-color: var(--pst-color-border); + background-color: var(--pst-color-secondary-bg); } &:after { - color: var(--pst-color-border); + color: var(--pst-color-secondary); content: var(--pst-icon-admonition-todo); } } @@ -288,6 +289,11 @@ aside.topic { margin: 0 0 0.5rem 0; } + // Over-ride text color to ensure enough contrast + p { + color: var(--pst-color-on-surface) !important; + } + // Over-ride large default padding ul.simple { padding-left: 1rem; diff --git a/src/pydata_sphinx_theme/assets/styles/content/_code.scss b/src/pydata_sphinx_theme/assets/styles/content/_code.scss index e20129ddf..8f4a264d3 100644 --- a/src/pydata_sphinx_theme/assets/styles/content/_code.scss +++ b/src/pydata_sphinx_theme/assets/styles/content/_code.scss @@ -51,6 +51,21 @@ div.literal-block-wrapper { code.literal { padding: 0.1rem 0.25rem; background-color: var(--pst-color-surface); - border: 1px solid var(--pst-color-on-surface); + border: 1px solid var(--pst-color-border); border-radius: 0.25rem; } + +a > code { + color: var(--pst-color-inline-code-links); +} + +// Fix for Sphinx's "highlight" directive - this is an issue with our accessible pygments theme +// and the colour we are using for the background of the code blocks. +html[data-theme="light"] .highlight .nf { + color: #0078a1 !important; +} + +// Minimum opacity needed for linenos to be WCAG AA conformant +span.linenos { + opacity: 0.8 !important; +} diff --git a/src/pydata_sphinx_theme/assets/styles/content/_quotes.scss b/src/pydata_sphinx_theme/assets/styles/content/_quotes.scss index e52b9e6fc..093f297c3 100644 --- a/src/pydata_sphinx_theme/assets/styles/content/_quotes.scss +++ b/src/pydata_sphinx_theme/assets/styles/content/_quotes.scss @@ -7,7 +7,7 @@ blockquote { position: relative; p { - color: var(--pst-color-text-muted); + color: var(--pst-color-text-base); } // remove padding from included line-block to avoid duplication @@ -20,7 +20,7 @@ blockquote { margin-bottom: 0; } - @include background-from-color-variable(--pst-color-border); + @include background-from-color-variable(--pst-color-on-background); //hack to make the text in the blockquote selectable &:before { diff --git a/src/pydata_sphinx_theme/assets/styles/content/_spans.scss b/src/pydata_sphinx_theme/assets/styles/content/_spans.scss index 4eb5ad182..cdda6e75b 100644 --- a/src/pydata_sphinx_theme/assets/styles/content/_spans.scss +++ b/src/pydata_sphinx_theme/assets/styles/content/_spans.scss @@ -12,7 +12,7 @@ span.guilabel { margin: auto 2px; position: relative; - @include background-from-color-variable(--pst-color-info); + @include background-from-color-variable(--pst-color-info-bg); } a.reference.download:before { diff --git a/src/pydata_sphinx_theme/assets/styles/extensions/_copybutton.scss b/src/pydata_sphinx_theme/assets/styles/extensions/_copybutton.scss index ce8ebb6d0..be6c887f7 100644 --- a/src/pydata_sphinx_theme/assets/styles/extensions/_copybutton.scss +++ b/src/pydata_sphinx_theme/assets/styles/extensions/_copybutton.scss @@ -22,6 +22,7 @@ div.highlight button.copybtn { &:hover { &:not(.success) { color: var(--pst-color-text); + background-color: var(--pst-color-shadow); } } diff --git a/src/pydata_sphinx_theme/assets/styles/extensions/_sphinx_design.scss b/src/pydata_sphinx_theme/assets/styles/extensions/_sphinx_design.scss index b7a193387..c18935846 100644 --- a/src/pydata_sphinx_theme/assets/styles/extensions/_sphinx_design.scss +++ b/src/pydata_sphinx_theme/assets/styles/extensions/_sphinx_design.scss @@ -5,8 +5,9 @@ * NOTE: sphinx-design uses !important quite liberally, so here we must do the * same for our overrides to have any effect. */ - -@use "../variables/color" as pstcol; +@use "../variables/color" as pst-color; +@use "sass:meta"; +@use "sass:color"; /******************************************************************************* * Color and variables @@ -29,14 +30,6 @@ $sd-semantic-color-names: ( "white" ); -/* Here we incorporate a modified version of sphinx-design's text-color - * function, to make sure that text is legible on colored buttons and badges. - * https://github.com/executablebooks/sphinx-design/blob/9226a12a/style/_colors.scss#L45-L47 - */ -@function text-color($value) { - @return if(lightness($value) > 70, #000, #fff); -} - /** * Here we create some extra --pst-color-* variables and use * them to override the value of the corresponding sphinx-design variables. @@ -48,34 +41,71 @@ $sd-semantic-color-names: ( * First, define the extra keys needed to cover the full range of semantic * color names used in sphinx-design, then merge them with the names we * already define for our own needs. + * see https://sphinx-design.readthedocs.io/en/latest/css_variables.html */ $extra-semantic-colors: ( - "dark": map-get(pstcol.$pst-semantic-colors, "text-base"), - "muted": map-get(pstcol.$pst-semantic-colors, "text-muted"), - "light": rgb(201, 201, 201), - "black": rgb(0, 0, 0), - "white": rgb(255, 255, 255), + "white": $foundation-white, + "light": ( + light: $foundation-light-gray, + bg-light: color.scale($foundation-light-gray, $lightness: 30%), + dark: $foundation-light-gray, + bg-dark: color.scale($foundation-light-gray, $lightness: -30%), + ), + "muted": ( + light: $foundation-muted-gray, + bg-light: color.scale($foundation-muted-gray, $lightness: 30%), + dark: $foundation-light-gray, + bg-dark: color.scale($foundation-muted-gray, $lightness: -30%), + ), + "dark": $foundation-dark-gray, + "black": $foundation-black, ); -$all-colors: map-merge(pstcol.$pst-semantic-colors, $extra-semantic-colors); +$all-colors: map-merge($pst-semantic-colors, $extra-semantic-colors); + +@mixin create-sd-colors($value, $name) { + // define the pst variables, so that downstream user overrides will work + --pst-color-#{$name}: #{$value}; + // we are now using a11y-combination to calculate the text color - this is based + // on the WCAG color contrast guidelines + --pst-color-#{$name}-text: #{a11y-combination($value)}; + //TODO: highlight seems to be used for buttons @trallard to fix on a11y follow-up work + --pst-color-#{$name}-highlight: #{darken($value, 15%)}; + // override the sphinx-design variables + --sd-color-#{$name}: var(--pst-color-#{$name}); + --sd-color-#{$name}-text: var(--pst-color-#{$name}-text); + //TODO: highlight seems to be used for buttons @trallard to fix on a11y follow-up work + --sd-color-#{$name}-highlight: var(--pst-color-#{$name}-highlight); +} // Now we override the --sd-color-* variables. @each $mode in (light, dark) { html[data-theme="#{$mode}"] { + // check if this color is defined differently for light/dark @each $name in $sd-semantic-color-names { - // check if this color is defined differently for light/dark - $value: map-get($all-colors, $name); - @if type-of($value) == map { - $value: map-get($value, $mode); + $definition: map-get($all-colors, $name); + @if type-of($definition) == map { + @each $key, $value in $definition { + @if str-index($key, $mode) != null { + // since now we define the bg colours in the semantic colours and not + // by changing opacity, we need to check if the key contains bg and the + // correct mode (light/dark) + @if str-index($key, "bg") != null { + --sd-color-#{$name}-bg: #{$value}; + // create local variable + $bg-var: --sd-color-#{$name}-bg; + $value: check-color($value); + --sd-color-#{$name}-bg-text: #{a11y-combination($value)}; + } @else { + $value: check-color($value); + @include create-sd-colors($value, $name); + } + } + } + } @else { + $value: map-get($all-colors, $name); + @include create-sd-colors($value, $name); } - // define the pst variables, so that downstream user overrides will work - --pst-color-#{$name}: #{$value}; - --pst-color-#{$name}-text: #{text-color($value)}; - --pst-color-#{$name}-highlight: #{darken($value, 15%)}; - // override the sphinx-design variables - --sd-color-#{$name}: var(--pst-color-#{$name}); - --sd-color-#{$name}-text: var(--pst-color-#{$name}-text); - --sd-color-#{$name}-highlight: var(--pst-color-#{$name}-highlight); } } } @@ -106,6 +136,7 @@ html[data-theme="light"] { .bd-content .sd-card { border: 1px solid var(--pst-color-border); + // TODO - --pst-color-panel-background is not defined... where is this coming from? .sd-card-header { background-color: var(--pst-color-panel-background); border-bottom: 1px solid var(--pst-color-border); @@ -131,11 +162,10 @@ html[data-theme="light"] { color: var(--pst-color-primary); } - // hover label + // Hover label &:not(:checked) + label:hover { - border-color: var(--pst-color-primary); - color: var(--pst-color-primary); - opacity: 0.5; + border-color: var(--pst-color-secondary); + color: var(--pst-color-secondary); } } @@ -145,16 +175,16 @@ html[data-theme="light"] { // Hovered label html &:hover { - color: var(--pst-color-primary); - border-color: var(--pst-color-primary); - opacity: 0.5; + color: var(--pst-color-secondary); + border-color: var(--pst-color-secondary); } } } /******************************************************************************* - * Dropdowns - */ +* Dropdowns +*/ + details.sd-dropdown { // Remove all borders to over-ride SD behavior, and we'll add our own later border: 0px !important; @@ -164,7 +194,6 @@ details.sd-dropdown { border: 0; } } - // Drop shadow should behave same as admonitions @include box-shadow(); @@ -176,40 +205,49 @@ details.sd-dropdown { font-weight: 600; padding-top: 0.5rem; padding-bottom: 0.5rem; - color: var(--pst-color-text) !important; // Set a variable that we can re-use for colors later // We must set this in the current and content sibling container // so that it is defined in both places - --pst-sd-dropdown-color: var(--sd-color-card-border); + --pst-sd-dropdown-color: var(--pst-gray-500); + --pst-sd-dropdown-bg-color: var(--pst-color-surface); & + div.sd-summary-content { --pst-sd-dropdown-color: var(--sd-color-card-border); } @each $name in $sd-semantic-color-names { &.sd-bg-#{$name} { --pst-sd-dropdown-color: var(--sd-color-#{$name}); + --pst-sd-dropdown-bg-color: var(--sd-color-#{$name}-bg); // Otherwise it won't be defined in the sibling element & + div.sd-summary-content { --pst-sd-dropdown-color: var(--sd-color-#{$name}); + --pst-sd-dropdown-bg-color: var(--sd-color-#{$name}-bg); } } + &.sd-bg-text-#{$name} { + // Use the WCAG conformant text color + color: var(--sd-color-#{$name}-bg-text) !important; + } } // Background color and border are grey by default background-color: unset !important; - @include background-from-color-variable(--pst-sd-dropdown-color); + @include background-from-color-variable(--pst-sd-dropdown-bg-color); // Add a left border with the same structure as our admonitions border-left: 0.2rem solid var(--pst-sd-dropdown-color) !important; & + div.sd-summary-content { border-left: 0.2rem solid var(--pst-sd-dropdown-color) !important; border-bottom-left-radius: calc(0.25rem - 1px); + background-color: var(--pst-color-on-background); } - span.sd-summary-icon { display: inline-flex; align-items: center; color: var(--pst-sd-dropdown-color) !important; + svg { + opacity: 1; + } } // Positioning of the caret diff --git a/src/pydata_sphinx_theme/assets/styles/sections/_announcement.scss b/src/pydata_sphinx_theme/assets/styles/sections/_announcement.scss index b2287d6aa..34f983c13 100644 --- a/src/pydata_sphinx_theme/assets/styles/sections/_announcement.scss +++ b/src/pydata_sphinx_theme/assets/styles/sections/_announcement.scss @@ -18,15 +18,14 @@ margin: 0; } - // The same background color transparency hack we use in admonitions + // Bg color is now defined in the theme color palette - using our secondary color &:after { position: absolute; width: 100%; height: 100%; left: 0; top: 0; - background-color: var(--pst-color-info); - opacity: 0.2; + background-color: var(--pst-color-secondary-bg); content: ""; z-index: -1; // So it doesn't hover over the content } @@ -34,4 +33,8 @@ &:empty { display: none; } + + a { + color: var(--pst-color-inline-code-links); + } } diff --git a/src/pydata_sphinx_theme/assets/styles/variables/_color.scss b/src/pydata_sphinx_theme/assets/styles/variables/_color.scss index 93fd94d7a..e658ae062 100644 --- a/src/pydata_sphinx_theme/assets/styles/variables/_color.scss +++ b/src/pydata_sphinx_theme/assets/styles/variables/_color.scss @@ -2,79 +2,231 @@ * master color map. Only the colors that actually differ between light and dark * themes are specified separately. * -* NOTE: this theme defines "info == primary" and "warning == secondary" +* To see the full list of colors see https://www.figma.com/file/rUrrHGhUBBIAAjQ82x6pz9/PyData-Design-system---proposal-for-implementation-(2)?node-id=1234%3A765&t=ifcFT1JtnrSshGfi-1 */ + +/** +* Function to get items from nested maps +*/ +// @param {Map} $map - Map +// @param {Arglist} $keys - Keys to fetch +// @return {*} +@function map-deep-get($map, $keys...) { + @each $key in $keys { + $map: map-get($map, $key); + } + @return $map; +} + +/* Assign base colors for the PyData theme */ +$color-palette: ( + // Primary color + "teal": + ( + "50": #f4fbfc, + "100": #e9f6f8, + "200": #d0ecf1, + "300": #abdde6, + "400": #3fb1c5, + "500": #0a7d91, + "600": #085d6c, + "700": #064752, + "800": #042c33, + "900": #021b1f, + ), + // Secondary color + "violet": + ( + "50": #f4eefb, + "100": #e0c7ff, + "200": #d5b4fd, + "300": #b780ff, + "400": #9c5ffd, + "500": #8045e5, + "600": #6432bd, + "700": #4b258f, + "800": #341a61, + "900": #1e0e39, + ), + // Neutrals + "gray": + ( + "50": #f9f9fa, + "100": #f3f4f5, + "200": #e5e7ea, + "300": #d1d5da, + "400": #9ca4af, + "500": #677384, + "600": #48566b, + "700": #29313d, + "800": #222832, + "900": #14181e, + ), + // Accent color + "pink": + ( + "50": #fcf8fd, + "100": #fcf0fa, + "200": #f8dff5, + "300": #f3c7ee, + "400": #e47fd7, + "500": #c132af, + "600": #912583, + "700": #6e1c64, + "800": #46123f, + "900": #2b0b27, + ), + "foundation": ( + "white": #ffffff, + // gray-900 + "black": #14181e, + ) +); + +:root { + // Add theme colours to the html root element + @each $group-color, $color in $color-palette { + @each $color-name, $definition in $color { + --pst-#{$group-color}-#{$color-name}: #{$definition}; + } + } +} + +// Static SCSS variables used thoroughout the theme +// Minimum contrast ratio used for the theme. +// Acceptable values for WCAG 2.0 are 3, 4.5 and 7. +// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast +// 4.5 - is for text that is 14pt or less +$min-contrast-ratio-4: 4.5; +// 3 is for text that is 18pt or bold, or for non-text elements +$min-contrast-ratio-3: 3; + +// Customize the light and dark text colors for use in our color contrast function. +$foundation-black: #14181e; +$foundation-white: #ffffff; +// This is a custom - calculated color between gray 100 and 200 - to reduce +// the contrast ratio (avoid a jarring effect) +$base-light-text: #ced6dd; +// used in sphinx_design - gray 100 +$foundation-light-gray: #f3f4f5; +// used in sphinx_design - gray 700 +$foundation-muted-gray: #29313d; +// used in sphinx_design - gray 800 +$foundation-dark-gray: #222832; + $pst-semantic-colors: ( - "primary": rgb(69, 157, 185), - "secondary": rgb(238, 144, 64), - "info": rgb(69, 157, 185), - "warning": rgb(238, 144, 64), - "success": ( - "light": rgb(40, 167, 69), - "dark": rgb(72, 135, 87), + "primary": ( + "light": #{map-deep-get($color-palette, "teal", "500")}, + "bg-light": #{map-deep-get($color-palette, "teal", "200")}, + "dark": #{map-deep-get($color-palette, "teal", "400")}, + "bg-dark": #{map-deep-get($color-palette, "teal", "800")}, + ), + "secondary": ( + "light": #{map-deep-get($color-palette, "violet", "500")}, + "bg-light": #{map-deep-get($color-palette, "violet", "100")}, + "dark": #{map-deep-get($color-palette, "violet", "400")}, + "bg-dark": #{map-deep-get($color-palette, "violet", "800")}, + ), + "accent": ( + "light": #{map-deep-get($color-palette, "pink", "500")}, + "bg-light": #{map-deep-get($color-palette, "pink", "200")}, + "dark": #{map-deep-get($color-palette, "pink", "400")}, + "bg-dark": #{map-deep-get($color-palette, "pink", "800")}, ), - "attention": ( - "light": rgb(255, 193, 7), - "dark": rgb(220, 169, 15), + "info": ( + "light": #276be9, + "bg-light": #dce7fc, + "dark": #79a3f2, + "bg-dark": #06245d, ), + "warning": ( + "light": #f66a0a, + "bg-light": #f8e3d0, + "dark": #ff9245, + "bg-dark": #652a02, + ), + "success": ( + "light": #00843f, + "bg-light": #d6ece1, + "dark": #5fb488, + "bg-dark": #002f17, + ), + // This is is based on the warning color + "attention": + ( + "light": var(--pst-color-warning), + "bg-light": var(--pst-color-warning-bg), + "dark": var(--pst-color-warning), + "bg-dark": var(--pst-color-warning-bg), + ), "danger": ( - "light": rgb(220, 53, 69), - "dark": rgb(203, 70, 83), + "light": #d72d47, + "bg-light": #f9e1e4, + "dark": #e78894, + "bg-dark": #4e111b, ), "text-base": ( - "light": rgb(50, 50, 50), - // Black + 50 - "dark": rgb(206, 206, 206), - // White - 50 + "light": #{map-deep-get($color-palette, "gray", "800")}, + "dark": $base-light-text, ), "text-muted": ( - "light": rgb(100, 100, 100), - // Twice as far from 0 as base - "dark": rgb(166, 166, 166), - // Twice as far from 256 as base + "light": #{map-deep-get($color-palette, "gray", "600")}, + "dark": #{map-deep-get($color-palette, "gray", "400")}, + ), + "heading-color": ( + "light": #{$foundation-white}, + "dark": #{$foundation-black}, ), "shadow": ( - "light": rgb(216, 216, 216), - "dark": rgb(33, 33, 33), + "light": rgba(0, 0, 0, 0.1), + "dark": rgba(0, 0, 0, 0.2), ), "border": ( - "light": rgb(201, 201, 201), - "dark": rgb(192, 192, 192), + "light": #{map-deep-get($color-palette, "gray", "300")}, + "dark": #{map-deep-get($color-palette, "gray", "600")}, + ), + "border-muted": ( + "light": rgba(23, 23, 26, 0.2), + "dark": #{map-deep-get($color-palette, "gray", "700")}, ), "inline-code": ( - "light": rgb(232, 62, 140), - "dark": rgb(221, 158, 194), + "light": #{map-deep-get($color-palette, "pink", "600")}, + "dark": #{map-deep-get($color-palette, "pink", "300")}, + ), + "inline-code-links": ( + // need to make sure there is enough contrast against the code bg + "light": #{map-deep-get($color-palette, "teal", "600")}, + // keep primary color for dark mode + "dark": #{map-deep-get($color-palette, "teal", "400")}, ), "target": ( - "light": rgb(251, 229, 78), - "dark": rgb(71, 39, 0), + "light": #f3cf95, + "dark": #675c04, ), - // DEPTH COLORS + // DEPTH COLORS - you can see the elevation colours and shades + // in the Figma file https://www.figma.com/file/rUrrHGhUBBIAAjQ82x6pz9/PyData-Design-system---proposal-for-implementation-(2)?node-id=1492%3A922&t=sQeQZehkOzposYEg-1 // background: color of the canvas / the furthest back layer "background": ( - "light": rgb(255, 255, 255), - "dark": rgb(18, 18, 18), + "light": #{map-deep-get($color-palette, "foundation", "white")}, + "dark": #{map-deep-get($color-palette, "foundation", "black")}, ), // on-background: provides slight contrast against background // (by use of shadows in light theme) "on-background": ( - "light": rgb(255, 255, 255), - "dark": rgb(30, 30, 30), - ), - // surface: object set above the background (without shadows) - // Uses JupyterLab cell background colors in light/dark theme - "surface": - ( - "light": rgb(245, 245, 245), - "dark": rgb(33, 33, 33), + "light": #{map-deep-get($color-palette, "foundation", "white")}, + "dark": #{map-deep-get($color-palette, "gray", "800")}, ), + "surface": ( + "light": #{map-deep-get($color-palette, "gray", "100")}, + "dark": #{map-deep-get($color-palette, "gray", "700")}, + ), // on_surface: object on top of surface object (without shadows) "on-surface": ( - "light": rgb(225, 225, 225), - "dark": rgb(55, 55, 55), + "light": #{map-deep-get($color-palette, "gray", "800")}, + "dark": $foundation-light-gray, ), ); @@ -90,18 +242,29 @@ $pst-semantic-colors: ( */ @mixin theme-colors($mode) { // check if this color is defined differently for light/dark - @each $name, $value in $pst-semantic-colors { - @if type-of($value) == map { - $value: map-get($value, $mode); - } - & { - --pst-color-#{$name}: #{$value}; + @each $col-name, $definition in $pst-semantic-colors { + @if type-of($definition) == map { + @each $key, $val in $definition { + @if str-index($key, $mode) != null { + // since now we define the bg colours in the semantic colours and not + // by changing opacity, we need to check if the key contains bg and the + // correct mode (light/dark) + @if str-index($key, "bg") != null { + --pst-color-#{$col-name}-bg: #{$val}; + } @else { + --pst-color-#{$col-name}: #{$val}; + } + } + } + } @else { + --pst-color-#{$col-name}: #{$definition}; } } + // assign the "duplicate" colors (ones that just reference other variables) & { --pst-color-link: var(--pst-color-primary); - --pst-color-link-hover: var(--pst-color-warning); + --pst-color-link-hover: var(--pst-color-secondary); } // adapt to light/dark-specific content @if $mode == "light" { @@ -151,8 +314,8 @@ html:not([data-theme]) { } // assign classes too, for runtime use of theme colors -@each $name, $value in $pst-semantic-colors { - .pst-color-#{$name} { - color: var(--pst-color-#{$name}); +@each $col-name, $definition in $pst-semantic-colors { + .pst-color-#{$col-name} { + color: var(--pst-color-#{$col-name}); } } diff --git a/tests/test_a11y.py b/tests/test_a11y.py index e4a6821a0..0f07cea90 100644 --- a/tests/test_a11y.py +++ b/tests/test_a11y.py @@ -111,4 +111,4 @@ def test_axe_core_kitchen_sink( results = page.evaluate(f"axe.run('{selector}')") # Expect Axe-core to have found 0 accessibility violations - assert len(results["violations"]) == 0, pretty_axe_results(results) + assert len(results["violations"]) == 0, pretty_axe_results(results, selector) diff --git a/tests/utils/pretty_axe_results.py b/tests/utils/pretty_axe_results.py index 698d42efd..c5929e087 100644 --- a/tests/utils/pretty_axe_results.py +++ b/tests/utils/pretty_axe_results.py @@ -10,7 +10,7 @@ # assert(len(results["violations"])) == 0, pretty_axe_results(results) -def pretty_axe_results(results: dict) -> str: +def pretty_axe_results(results: dict, selector: str) -> str: """Create readable string that can be printed to console from the Axe-core results object. :param results: The object promised by `axe.run()`. @@ -30,6 +30,7 @@ def pretty_axe_results(results: dict) -> str: ) for tag in violation["tags"]: string += f" {tag}" + string += f"\n\tTested selector: {selector}" string += "\n\tElements Affected:" i = 1 for node in violation["nodes"]: