Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a unique CSS class to body tag which uses the docs ID #4280

Closed
Dannyholt opened this issue Feb 23, 2021 · 17 comments · Fixed by #6933
Closed

Add a unique CSS class to body tag which uses the docs ID #4280

Dannyholt opened this issue Feb 23, 2021 · 17 comments · Fixed by #6933
Labels
feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future.

Comments

@Dannyholt
Copy link

🚀 Feature

Can we get some CSS classes to the body tag or maybe main-wrapper which uses the docs id. This would allow us to style specific docs without impacting other docs on the site which may not want/need that styling. Similar to what WordPress does on their body tag which uses the page or posts unique ID.

The examples below grab the getting-started class from a doc with an ID of getting-started.

<body class="getting-started" style="overflow: visible;">
<div class="main-wrapper getting-started">

Have you read the Contributing Guidelines on issues?

Yes

Motivation

Currently we have a sidebar category called Getting Started which has a several docs such as System Requirements, Installation, Configuration and so forth. We also have a getting-started.md doc which has a bunch of information and a list of all docs in the Getting Started category.

This list is quite long and so would benefit from some simple CSS to style the list items into two columns. At the moment, this isn't really possible without impacting other lists on the site.

Pitch

This could be used in a variety of ways not just the simple scenario I explained above. I'm sure other users would find having a unique CSS class for a particular docs helpful in other styling scenarios as well.

@Dannyholt Dannyholt added feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future. status: needs triage This issue has not been triaged by maintainers labels Feb 23, 2021
@Simek
Copy link
Contributor

Simek commented Mar 14, 2021

Hi @Dannyholt, this PR should fix your issue:

It have introduced the new className ("main-docs-wrapper") for the docs plugin pages wrapper:

CC: @lex111

@Dannyholt
Copy link
Author

@Simek

Unfortunately, this won't fix my issue as I would prefer to target specific docs via CSS whereas the main-docs-wrapper will appear on all docs as far as I can tell. :)

What I'm after is let's imagine we have a doc called hello.md the wrapper would add the docs ID as a class. For example:

<div class="main-docs-wrapper hello">...</div>

Which you could then use to style elements for that doc only. For example:

#__docusaurus .hello .markdown ul {
  column-count: 2;
}

@Simek
Copy link
Contributor

Simek commented Mar 14, 2021

@Dannyholt Yeah, you are right, I didn't get the problem which you have correctly.

As a temporary workaround, if change should apply to only content of one, selected page, you can add className to the element or div wrapper with className around it. You can use HTML tags quite freely in MDX.

Here you can see the example of React Native components grid:

@slorber
Copy link
Collaborator

slorber commented Mar 15, 2021

This is quite related to #4322

We could add some unique classname to any doc/blog/markdown page to allow to target it more easily.
For docs, maybe a version classname could be useful too

@lex111
Copy link
Contributor

lex111 commented Jun 16, 2021

Closing since partially it is implemented in #4511

@lex111 lex111 closed this as completed Jun 16, 2021
@Josh-Cena Josh-Cena removed the status: needs triage This issue has not been triaged by maintainers label Mar 6, 2022
@Josh-Cena
Copy link
Collaborator

Reopening, because we still can't use CSS to target a specific doc page. I think there's value in using doc ID as class name of each doc's wrapper.

@Josh-Cena Josh-Cena reopened this Mar 6, 2022
@Josh-Cena Josh-Cena added the status: accepting pr This issue has been accepted, and we are looking for community contributors to implement this label Mar 6, 2022
@slorber
Copy link
Collaborator

slorber commented Mar 9, 2022

I think there's value in using doc ID as class name of each doc's wrapper.

The wrapper is a nested div, it's not the most flexible way to add a class.

What if the user wants to change the Docusaurus layout but only for a given doc instance, for a blog post, or a specific doc id?

I know those are quite unusual edge cases, but it's better if we apply those classes to the HTML tag: it would be more flexible and always suit all use-cases.

Some fancy use-cases can be: "Use a different navbar background color for docs vs blog"


The way we currently apply classes to the layout (pageClassName/wrapperClassName) is not the best option.

We can also see the problem in #6823 (comment) where it's not easy to split the doc routes into multiple layers and still prevent useless layout unmounts/remounts.

We don't have an equivalent to <Head><html className="docId"/></Head> that would add a class to the wrapper from a child (+ SSR support), and it doesn't permit to target layout items with custom CSS


I think it's worth doing a breaking change on those CSS class names, moving them at the top HTML element, so that:

@Josh-Cena
Copy link
Collaborator

Oh yeah, when I say "wrapper" I don't necessarily mean one particular div, but just any enclosing element. Applying it to html makes sense as well.

If you are open to a breaking change, then why not 👍

@slorber
Copy link
Collaborator

slorber commented Mar 17, 2022

As part of #6933, a doc route will now have the following classes on the top-level HTML element:

plugin-docs 
plugin-id-default 
docs-version-2.0.0-beta.16 
docs-doc-id-introduction

This means you should be able to write:

.plugin-docs.docs-doc-id-introduction .label { 
  color: red
}

Are these class names looking good to you?

Do you have a better suggestion?

Would using data-attribute be a better fit or a good-enough alternative?
I mean something like:

[data-docs-doc-id-introduction] .label { 
  color: red
}

Also, the "docs version" selector docs-version-2.0.0-beta.16 was already there, but it looks suspicious to me to have dots 😅 not sure it's valid

@slorber slorber removed the status: accepting pr This issue has been accepted, and we are looking for community contributors to implement this label Mar 17, 2022
@slorber
Copy link
Collaborator

slorber commented Mar 18, 2022

The version html className is configurable through config so I guess it's good enough for now. We'd probably need some logic to sanitize random strings to valid classNames at some point though

@slorber
Copy link
Collaborator

slorber commented Mar 18, 2022

also thinking we could add a html_class_name frontMatter

it should also be possible to add the current sidebar to HTML classes? 🤷‍♂️

Let me know if you have a good use-case for this

@Josh-Cena
Copy link
Collaborator

also thinking we could add a html_class_name frontMatter

Our pages plugin has an (undocumented) wrapperClassName front matter which IMO makes sense

@slorber
Copy link
Collaborator

slorber commented Mar 18, 2022

Our layout has also this undocumented wrapperClassName that I kept for retro-compatibility (used on a few likes like React-Native)

I think it also makes sense to keep it and be able to apply a className to the layout wrapper, just above the children. But by default applying classes to HTML is more flexible


We could also generalize a layout_wrapper_class_name to all md frontMatter maybe?

But it may be complicated because the doc layout is declared above the doc itself (to prevent unmount/remount) so it can't easily apply a custom class to the parent layout.

Same problem as #6823 (comment)

@Samrose-Ahmed
Copy link

is it documented how to set a class name on the root? I am trying to add custom styles to the navbar of a page created through Layout component.

@slorber
Copy link
Collaborator

slorber commented Jul 25, 2022

@Samrose-Ahmed you can definitively do that.

See https://docusaurus.io/tests : each section has a different navbar border, because each plugin/page has a custom HTML className to target more selectively

For custom React pages you'd have to use the following:

<Head>
  <html className="my-custom-page-className"/>
</Head>

Note with Head, one HTML className overrides attribute of parents, in case you want to "compose" and avoid overriding a className set upper in the React tree, you'd have to use our undocumented helper:

import {HtmlClassNameProvider} from '@docusaurus/theme-common';

@pavelkornev
Copy link

pavelkornev commented Jan 18, 2023

<Head>
  <html className="my-custom-page-className"/>
</Head>

@slorber is it possible to do the same on <body/>? I mean i don't see a Provider for the body.

@slorber
Copy link
Collaborator

slorber commented Jan 18, 2023

<Head>
  <html className="my-custom-page-className"/>
</Head>

@slorber is it possible to do the same on <body/>? I mean i don't a Provider for the body.

Similarly you can copy/paste our HtmlClassNameProvider code and make it work for body if you want to. We don't necessarily plan to provide or use this feature on Docusaurus, and adding a class to HTML is enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants