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

rustdoc styling improvements for readability #59845

Open
7 of 11 tasks
lambda opened this issue Apr 10, 2019 · 16 comments
Open
7 of 11 tasks

rustdoc styling improvements for readability #59845

lambda opened this issue Apr 10, 2019 · 16 comments
Labels
A-rustdoc-ui Area: Rustdoc UI (generated HTML) T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Comments

@lambda
Copy link
Contributor

lambda commented Apr 10, 2019

This is being broken out of #59829 to provide smaller, actionable items that can be independently discussed and worked on.

Comparing the overall rustdoc styling with recommendations for accessibility, including for dyslexia and attention disorders, there are a number of improvements that could be made.

In addition, the mdBook default styling, which is already used for the Rust Book and other official Rust documentation, already meets or comes closer to meeting several of these criteria, so one way to achieve several of these goals would be to unify styling with mdBook.

A few of these recommendations may be more appropriate for a separate theme rather than the default theme, but I think many of these changes could improve readability and usability for all users.

  • Remove extraneous horizontal rules; horizontal rules should generally be used sparingly, but are used heavily in rustdoc. Appropriate spacing and sizing of headers can replace most uses of horizontal rules.
  • Use a sans-serif font for the body text
  • Change the font size and column width such that lines are at most 100 characters wide, preferably under 80. This probably means also limiting width of example code to 70 or 80 columns or so, but that's probably OK, example code shouldn't need as much room as the standard convention of 100 columns.
  • Consider a lower contrast theme, either as the default or as an option distinct from the dark theme. This can be overdone, some sites go overboard with low-contrast themes, but there's a lot of room for going lower contrast before getting to that point.
  • Reduce use of color, as colored text can catch attention and the more colors used the more distracting it can be. Additionally, relying on color to convey information presents problems for those with colorblindness.
    • Consider removing use of different colors for links to different kinds of items (structs, enums, type aliases, macros, etc). This may be worth its own issue as it interacts with the search UI. rustdoc: use smaller number of colors to distinguish items #91480
    • Consider removing colored headings; headings are already distinguished by size, font, spacing, and horizontal rules (though those should probably be also be dropped). In general, only one or two attributes should change to distinguish headings, otherwise they become too prominent and can drown out the text.
    • Consider removing the color from the "Run" link in the example code, or only coloring it upon hover. Also consider unifying styling of example code "Run" link with mdBook, though mdBook could also use lower contrast controls by default. Make Run button visible on hover #92058
  • Reduce or eliminate the use of background boxes for inline <code> spans; the Python approach of not having a background box if it is already highlighted as a link seems like a nice idea.
  • Increase leading to 1.5 times the font size, and greater inter-paragraph spacing (WCAG recommends 250% of the line height, but that looks quite excessive to me; 2em looks like a readability improvement to me without being excessive) rustdoc: tweak line spacing and paragraph spacing for accessibility #93694
  • Provide a theme with a larger font size, or use a 1 rem default font size to pick up the browser default font size (increasing the font size across the board doesn't necessarily improve readability; some users actually find smaller fonts more readable) Set font size proportional to user's font size #92448
@jonas-schievink jonas-schievink added the T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. label Apr 10, 2019
@Diggsey
Copy link
Contributor

Diggsey commented Apr 25, 2019

IMO, there should definitely be no distinction in colour between enums, structs and type aliases - either it's an opaque type in which case you shouldn't even care how the type was defined in the library, or else you need to use the type, in which case you need to go to the documentation for that type anyway.

Traits should be a different colour, but shouldn't be the current bright blue that overpowers everything else - the most important things in the method list are the name of the method, followed by its arguments and return type, and yet these are the least visually distinct of anything on the page.

@lambda
Copy link
Contributor Author

lambda commented May 7, 2019

In a comment on #59851, @measlytwerp posted a mockup that addresses the requests in that issue as well as many in this issue. For anyone interested in this issue, it would be worth taking a look at that mockup.

@camelid camelid added the A-rustdoc-ui Area: Rustdoc UI (generated HTML) label Oct 24, 2021
@jsha
Copy link
Contributor

jsha commented Nov 20, 2021

Consider removing use of different colors for links to different kinds of items (structs, enums, type aliases, macros, etc). This may be worth its own issue as it interacts with the search UI.

Here's a nice example showcasing a lot of different colors:

image

We've got umber for the method name, green for the Option (because it's an enum), black for self and I because they are placeholder types, purple for SliceIndex because it's a struct, teal for str because it's a primitive, and orange for Output because it's an associated type.

I agree with @Diggsey - we should keep a distinction for types vs traits. I think we should treat associated types in the same way as other placeholder types like self and I; so currently that would mean coloring them black.

Here's what it looks like if we color enums, primitives, structs, and unions (not pictured here) all the same, and decolor associated types:

image

Consolidating on fewer colors would also solve some distinguishability problems. For instance, the umber and orange are hard for me to distinguish, and the teal and green are hard for me to distinguish.

/cc @GuillaumeGomez

@jsha
Copy link
Contributor

jsha commented Nov 20, 2021

And here's a version where I took the colors for struct and trait (purple and blue) and lowered their value in the HSV color model to be closer to the value of the umber get (60).

struct (and friends): #9a3d7f
trait: #533ca3

image

I think those adjustments reduce the effect where the color on the traits overwhelms the method name. It might make trait and struct too indistinguishable, but if folks like the direction we could fiddle with it a bit more.

@jsha
Copy link
Contributor

jsha commented Nov 21, 2021

I wanted to get an impression of the colors we currently use, so I made a palette from the colors in the light theme:

rustdoc-colors

The groupings don't have particular meaning, except I tried to group together all the greys at the top, and roughly group some of the other prominent colors together. Also the lower right grouping is the colors used for code samples.

My main takeaway is: there are indeed a lot of colors! And I was surprised by how many different shades of grey we use.

I'd like to consolidate on a smaller number of core colors (perhaps six?), with some shades of them for emphasis (e.g. focus in search results). And around four shades of grey, plus white and black. I also don't want to change the basic appearance of rustdoc, which I think is good.

Here's a grouping of what I think are the core colors of rustdoc's light theme right now:

rustdoc-core-colors

That's the link color, method/function color, struct color, and trait color. Note that the trait color is just a bit brighter than its companions, which should probably be tweaked. All of these work pretty well according to this colorblindness simulator: https://www.color-blindness.com/coblis-color-blindness-simulator/. I also put these colors in Adobe's color tool, where you can play around with them a bit (click "create using theme"): https://color.adobe.com/rustdoc%20current%20theme-color-theme-18992096

So, as a concrete first step I propose:

  • enums, unions, primitive types, and foreign types should start using the color of structs.
  • associated types and trait aliases should start using the color of traits.
  • macros should start using the color of functions.
  • consts, statics, and keywords should start using black.
  • the trait color should be made slightly less bright, in line with the struct and link colors.

I think this will make the docs feel more consistent and predictable, and make it more practical for people to learn the meanings of the colors.

@GuillaumeGomez I'm particularly interested in your feedback because I know you've put in a lot of work on colors so far.

@jsha
Copy link
Contributor

jsha commented Nov 21, 2021

Here's a demo. I think it came out pretty well! https://rustdoc.crud.net/jsha/fewer-colors/std/primitive.str.html#method.get_mut

image

@Diggsey
Copy link
Contributor

Diggsey commented Nov 21, 2021

This seems like a good direction :)

associated types and trait aliases should start using the color of traits.

I would probably colour "associated types" as either types or normal text, rather than as traits. Other than that the choices makes sense.

@GuillaumeGomez
Copy link
Member

GuillaumeGomez commented Nov 21, 2021

I can provide you the original idea I had: I wanted to make it easy to spot different kind of types. However, it ended up making a lot of different colors and also becoming a distraction. So I like the idea of unifying some colors. The only thing I'm not sure is for the different color we should pick: should we keep colors which are close to each others or have them very different (like currently) to make it easy to spot them?

But in any case, having less colors is a good idea I think.

While we're at it, this will impact the source code pages as well. Should they follow the same rule or not? They don't have the same purpose after all.

also cc @rust-lang/rustdoc

@jsha
Copy link
Contributor

jsha commented Nov 21, 2021

I would probably colour "associated types" as either types or normal text, rather than as traits. Other than that the choices makes sense.

They shouldn't be styled in orchid (the struct color; thanks to shallowsky for the color names) because that should represent concrete types - i.e. a type that has a specific page for its documentation. I think you're right though that they also shouldn't be styled as traits. Normal text seems right. A caveat: Generally the style here is "colored text is a link; uncolored is not a link," but associated types are currently clickable. Maybe they don't need to be; in the get example I gave above, clicking on SliceIndex is just as good.

The only thing I'm not sure is for the different color we should pick: should we keep colors which are close to each others or have they very different (like currently) to make it easy to spot them?

It depends on the context and what we want to draw attention to. For instance, in a method heading, the most important distinction is "this is the method heading" / "these are the parameters". So making the method heading and parameters very different is good. A secondary distinction is "this is a trait" / "this is a concrete type". Since that's less important than the primary distinction, we don't want to draw as much attention to it. I think the orchid/slate blue distinction we have for concrete types vs traits is actually pretty good for that. In the demo I tweaked those colors a bit so everything has the same saturation and balance (in the HSB color model). They're now a little closer together and a little more harmonious IMO.

While we're at it, this will impact the source code pages as well. Should they follow the same rule or not? They don't have the same purpose after all.

I think source pages (and examples) should also follow the principle of using color to draw attention to meaningful difference, not every possible difference. As an example: we have colors for kw and kw-2. kw is for keywords like let, if, and for; kw-2 is for ref and mut. Those should be the same color.

Also worth considering (but not blocking) is whether source view should use color to highlight types (like we do in method headings) or keywords (like it does today). Highlighting keywords is what most IDEs do. Highlighting types would be consistent with the rest of rustdoc. But might lead people to believe they could click type names in examples, which they can't (and would probably be overkill to add). Also highlighting types would require knowing whether a type was concrete or a trait, which would rule out doing syntax highlighting via JS in the future (if we decided we wanted to do that and found a fast enough highlighter).

Also relevant: semantic highlighting: https://github.com/microsoft/vscode/wiki/Semantic-Highlighting-Overview and https://code.visualstudio.com/api/language-extensions/semantic-highlight-guide.

@GuillaumeGomez
Copy link
Member

It makes sense.

For the source code viewer, I don't think that the goal is the same as for the docs. Having syntax highlighting closer to a IDE's sounds more logical, no? You don't read source code as you read documentation after all.

@camelid
Copy link
Member

camelid commented Nov 21, 2021

Also highlighting types would require knowing whether a type was concrete or a trait, which would rule out doing syntax highlighting via JS in the future (if we decided we wanted to do that and found a fast enough highlighter).

Not really; we could always change the styling again if we really wanted to switch to JS for some reason.

@GuillaumeGomez
Copy link
Member

Forgot to precise but I'd much rather not need JS for syntax highlighting.

@camelid
Copy link
Member

camelid commented Nov 21, 2021

I think it's a good idea to reduce the number of colors. I have some comments:

I agree with Diggsey that we shouldn't color associated types as traits; it seems confusing.

A caveat: Generally the style here is "colored text is a link; uncolored is not a link," but associated types are currently clickable. Maybe they don't need to be; in the get example I gave above, clicking on SliceIndex is just as good.

I don't think we should remove the link; if we can get the user to what they're looking for faster, we should. What if a trait has a lot of top-level documentation before the associated types are documented?


consts, statics, and keywords should start using black.

I disagree with this. Then the const name is not distinguished from the keywords around it, and it brings up the "uncolored text is not a link" thing too.


I also think we should focus on the main doc colors and ignore syntax highlighting for now. IMO our syntax highlighting is good enough, and people are used to lots of colors with syntax highlighting.


Overall, I think we should start small. For example, I suggest we start by (at least considering) coloring structs, enums, and unions the same.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Dec 31, 2021
rustdoc: use smaller number of colors to distinguish items

This reduces visual distractions when reading method signatures.

As discussed in rust-lang#59845 (comment), this categorizes items into one of six colors (down from thirteen):

 - method, function (ochre `#AD7C37`)
 - trait, trait alias (dark slate blue `#6E4FC9`)
 - enum, struct, type alias, union, primitive (maroon `#AD378A`)
 - static, module, keyword, associated type, foreign type (steel blue `#3873AD`)
 - macro (green `rust-lang#68000`)
 - generic params, self, Self (unmarked black `#000000`)

I slightly tweaked the actual color values so they'd have the same lightness (previously the trait color stood out much more than the others). And I made the color for links in general consistently use steel blue (previously there was a slightly different color for "search-failed").

The ayu and dark themes have been updated according to the same logic. I haven't changed any of the color values in those themes, just their assignment to types.

Demo:

https://rustdoc.crud.net/jsha/fewer-colors/std/string/struct.String.html
https://rustdoc.crud.net/jsha/fewer-colors/std/vec/struct.Vec.html
https://rustdoc.crud.net/jsha/fewer-colors/std/io/trait.Read.html
https://rustdoc.crud.net/jsha/fewer-colors/std/iter/trait.Iterator.html
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 5, 2022
…omez

Set font size proportional to user's font size

According to MDN (https://developer.mozilla.org/en-US/docs/Web/CSS/font-size),

> To maximize accessibility, it is generally best to use values that are relative to the user's default font size.

> Defining font sizes in px is not accessible, because the user cannot change the font size in some browsers.

Note that changing font size (in browser or OS settings) is distinct from the zoom functionality triggered with Ctrl/Cmd-+. Zoom
functionality increases the size of everything on the page, effectively applying a multiplier to all pixel sizes. Font size changes apply to just text.

For relative font sizes, we could use `em`, as we do in several places already. However that has a problem of "compounding" (see MDN article for details). The compounding problem is nicely solved by `rem`, which make font sizes relative to the root element, not the parent element.

Since we were using a hodge-podge of pixel sizes, em, rem, and percentage sizes before, this change switches everything to rem, while keeping the same size relative to our old default of 16px.

16px is still the default on most browsers, for users that haven't set a larger or smaller font size.

Part of rust-lang#59845. Note: this will conflict with rust-lang#92404. We should merge that first (once it's done) and I'll resolve the merge conflicts.

r? `@GuillaumeGomez`

Demo: https://rustdoc.crud.net/jsha/font-size-access/std/string/struct.String.html
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 6, 2022
@jsha
Copy link
Contributor

jsha commented Jan 7, 2022

Use a sans-serif font for the body text

I looked pretty hard for research that supported better readability for sans-serif text. There are a decent number of articles that cite this based on conventional design wisdom, but the research indicates no significant difference. For example https://geniusee.com/single-blog/font-readability-research-famous-designers-vs-scientists. I'm inclined to WONTFIX this aspect unless we can find some solid citations that sans-serif is better. Also, the Web Content Accessibility Guidelines on visual presentation don't mention font style one way or the other.

Change the font size and column width such that lines are at most 100 characters wide, preferably under 80. This probably means also limiting width of example code to 70 or 80 columns or so, but that's probably OK, example code shouldn't need as much room as the standard convention of 100 columns.

I also wasn't able to find good citations on the most readable column width for general purpose reading. What I found suggested that the best column width varied depending on the type of information being presented and the format, and that ranging up to about 120 was reasonable. For instance narrow columns work well in newspapers but not as well on the screen. Our current max-width goes to about 120 or 130 depending on what type of characters are in the line.

I think we should very slightly narrow the column width so it ranges from ~110-120. That will also let us widen the sidebar a little without changing the overall max-width.

Increase leading to 1.5 times the font size, and greater inter-paragraph spacing (WCAG recommends 250% of the line height, but that looks quite excessive to me; 2em looks like a readability improvement to me without being excessive)

The WCAG guidelines linked only require that "a mechanism is available to achieve" leading of 1.5. The default doesn't need to be that way. So for instance we could add a "tall and narrow" theme that applies the leading changes and the column width changes from the WCAG guidelines.

@jsha
Copy link
Contributor

jsha commented Jan 7, 2022

By the way, one of the WCAG items is "a mechanism is available to achieve:"

Foreground and background colors can be selected by the user.

One of the techniques to do this is https://www.w3.org/WAI/WCAG21/Techniques/general/G148:

Not specifying background color, not specifying text color, and not using technology features that change those defaults

Right now we do specify background color and text color explicitly. For instance in light.css we set the background color to white, and the foreground color to black. Instead we should leave those unmodified, and let the user-agent style control them. Note: I wasn't able to find a way to set user-agent colors in Chrome but you can do it in the Firefox settings.

We can do the same for the ayu theme, I think: let the user-agent control the foreground and background (which default to white and black). For 'dark' it's harder, because that theme wants a non-default background color.

Edit: It turns out Firefox's color settings also let you override the page settings. That is more effective than leaving the default foreground/background in our CSS. For instance, if we leave the default foreground/background, things like the sidebar (grey background) and code blocks (grey background) still don't respond to user configuration in the user-agent. So I think we shouldn't try to do something special for color here.

@Nemo157
Copy link
Member

Nemo157 commented Jan 7, 2022

We can do the same for the ayu theme, I think: let the user-agent control the foreground and background (which default to white and black).

Firefox doesn't appear to change the default colors when in dark mode for me, it stays at black on white for an unstyled webpage (and ayu isn't pure black and white).

JohnTitor added a commit to JohnTitor/rust that referenced this issue Feb 9, 2022
…eGomez

rustdoc: tweak line spacing and paragraph spacing for accessibility

The [W3C Web Content Accessibility Guidelines](https://www.w3.org/WAI/WCAG21/Understanding/visual-presentation.html) specify a minimum line spacing of 1.5 and a minimum paragraph spacing of 1.5 times the line spacing. Our current line spacing (implemented by line-height) is 1.4, so it's a small bump to go up to 1.5. Similarly, we have a paragraph spacing of 0.6em. Bump that to 0.75em (which is 1.5 times the 0.5em distance between lines).

Also, fix all the font sizes so instead of being round-ish numbers in rem (like 1.1rem, 1.2rem), they are round numbers in pixels: 16px, 18px, 20px, 22px, 24px. Ensure each font size is at least 2 pixels different than the nearest other font size, so distinctions can be clearly seen. Overall the font-sizes are mostly staying the same, being rounded up or down as appropriate. This will make reasoning about consistent layout sizes much easier.

Remove a few unused styles.

Simplify the display of the mobile-topbar location, by setting its margins to auto rather than trying to size it exactly to the topbar.

Part of rust-lang#59845.

Demo: https://rustdoc.crud.net/jsha/font-sizes-spacing/std/string/struct.String.html

r? `@GuillaumeGomez`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rustdoc-ui Area: Rustdoc UI (generated HTML) T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants