Prevent text from overflowing in various cases#756
Conversation
🦋 Changeset detectedLatest commit: 7982b0c The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
👷 Deploy Preview for astro-starlight processing.
|
4714016 to
4981cc1
Compare
| margin-inline-start: var(--sl-sidebar-item-padding-inline); | ||
| border-inline-start: 1px solid var(--sl-color-hairline-light); | ||
| padding-inline-start: var(--sl-sidebar-item-padding-inline); | ||
| overflow-wrap: break-word; |
There was a problem hiding this comment.
There was a problem hiding this comment.
Ohhh good catch! I've added this use case in the commit so that we can test it.
So I've dropped this rule and added instead the following which is less specific:
.top-level > li {
overflow-wrap: anywhere;
}| ul :global(.sl-badge) { | ||
| max-width: 100%; | ||
| } |
There was a problem hiding this comment.
I think an alternative solution could be to not do that and use overflow-wrap: anywhere; instead of overflow-wrap: break-word; in the <Badge/> component. This would mean that we would not have to do that every time we use a badge in a similar context.
Any thoughts?
There was a problem hiding this comment.
Neat, it works pretty well! So obviously, this is way better in terms of usage since there's nothing to do while using the component.
I was a bit worried about overflow-wrap: anywhere browser support for Safari which is only from 15.4.
But the team confirmed that other features used in Astro and/or Starlight are only working from Safari 15.4.
I ran some tests with BrowserStack with Safari 15.3 just to see how's the fallback in our specific use case, but it's impossible to say what's happening:
I don't have access to any Safari 15.4, but from 16, everything's rendered as what you can see in your browser right now deployed by Netlify. Double-checked with various versions of Chrome and Firefox and seems to be good to go with this solution 🚀
| summary > h2 { | ||
| width: calc(100% - 1.25rem); | ||
| } | ||
|
|
There was a problem hiding this comment.
Tried some flex-shriking on the caret without success.
What issues did you encounter? Disabling shrinking using flex-shrink: 0; on the caret icon and using overflow-wrap: anywhere; on the title seems to do the trick for me but I may be missing something.
There was a problem hiding this comment.
Tried it in combination with overflow-wrap: break-word and not anywhere. It works way better now, thanks for the trick.
So I've dropped this rule and used overflow-wrap: anywhere here + used flex-shrink :0 on the caret.
More globally I've made this same exact change everywhere (overflow-wrap: break-word -> overflow-wrap: anywhere)
| svg + span { | ||
| width: calc(100% - 1.5rem); | ||
| } |
There was a problem hiding this comment.
If I am not missing something, I guess like in the <SidebarSublist/> component, this could be avoided by using overflow-wrap: anywhere; instead of overflow-wrap: break-word; for the link.
Any thoughts?
There was a problem hiding this comment.
Based on the previous comments and fixes, this has been removed.
There was a problem hiding this comment.
This one is a bit trickier indeed.
The current approach will break the existing wrapping behavior on small width screens:
| Before | After |
|---|---|
![]() |
![]() |
It also looks like this would not work when you are on a page where both the previous and next links are fairly long:
Not sure yet what would be the best approach here, might need to think about it a bit more 🤔
There was a problem hiding this comment.
Good catch, I didn't test at the right breakpoints for mobile. So I've tried something with a @media rule to handle the 2 types of rendering: 1 row, 2 rows:
a {
/* ... */
width: 100%;
flex-basis: calc(100% - 0.5rem);
/* ... */
}
@media (min-width: 29.6em) {
a {
width: 50%;
flex-basis: calc(50% - 1rem);
}
}Note that 29.6em might be a lil' bit magical here. I've found this value by comparing the rendering between this branch and the main branch. The switch between 1 row to 2 rows was between 473px and 474px which led me to that 29.6em. Obviously, can be changed to something like 30em or other values.
Being still a bit tricky to test, I hope that I've covered most of the use cases 😅
There was a problem hiding this comment.
Currently inside Starlight we only use (min-width: 50rem) and (min-width: 72rem). Would love to keep us to that consistency if possible.
This is definitely one of the trickier ones. I also think it’s one of the less crucial ones, so we could also decide to split out fixing this one into a follow-up PR if figuring it out will otherwise block this PR.
There was a problem hiding this comment.
I definitely can understand that we prefer to stick with only (min-width: 50rem) and (min-width: 72rem). I've made some tests with container queries that could help but they are not available before Safari 16.
So I dropped this whole modification and I'll try to tackle it in a separate PR: #814
|
Please note that I haven't yet updated the description of the PR with the new modifications. I'm waiting for an agreement on the final solution with the first code review since the description is a bit heavy to update. Hope you don't mind. |
HiDeoo
left a comment
There was a problem hiding this comment.
From all the cases/pages I tested, the new changes look great. Let's see if some other people find more edge cases or not.
I'm not particularly a huge fan of the changes for the next/prev links but I have yet to find a more elegant solution not breaking anything.
Btw, did you investigate the CI / Check for accessibility issues failure or do you want me to take a look at it? (note: to run them locally you can NO_GRADIENTS=true pnpm build && pnpm test)
Neither do I.
Not yet, I'll check this out ASAP. |
|
Thanks for the investigation. Interesting. Even more interesting is that if I switch locally to this branch and run the tests on my machine, they pass. I guess it depends on the window size which depends on the screen resolution maybe? I assumed that the window size would be fixed, but it seems that it is not or something else is going on. Nonetheless, I guess this is indeed something that should be fixed in another PR as when reverting your temporary long texts, the tests should pass again. |
71cfbfe to
9df0e55
Compare
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
FYI I've updated the description so that it reflects the final changes, squashed the commits, and split them so that it is easier for you to remove the long text tests when the PR is considered ready to merge (you'll just have to drop 9df0e55). |
delucis
left a comment
There was a problem hiding this comment.
Thanks for tackling all of these edge cases @julien-deramond! Really nice work. Left a couple of notes to try to help get this PR over the line! 🙌
There was a problem hiding this comment.
Currently inside Starlight we only use (min-width: 50rem) and (min-width: 72rem). Would love to keep us to that consistency if possible.
This is definitely one of the trickier ones. I also think it’s one of the less crucial ones, so we could also decide to split out fixing this one into a follow-up PR if figuring it out will otherwise block this PR.
| .top-level > li { | ||
| overflow-wrap: anywhere; | ||
| } |
There was a problem hiding this comment.
Should this really only apply to the top-level list, or any li?
There was a problem hiding this comment.
The components being black boxes, it's safe to apply the rule directly to li as defensive CSS. I've changed it to:
diff --git a/packages/starlight/components/SidebarSublist.astro b/packages/starlight/components/SidebarSublist.astro
index c4c5882..63308f6 100644
--- a/packages/starlight/components/SidebarSublist.astro
+++ b/packages/starlight/components/SidebarSublist.astro
@@ -53,6 +53,10 @@ interface Props {
padding: 0;
}
+ li {
+ overflow-wrap: anywhere;
+ }
+
ul ul li {
margin-inline-start: var(--sl-sidebar-item-padding-inline);
border-inline-start: 1px solid var(--sl-color-hairline-light);
@@ -65,10 +69,6 @@ interface Props {
color: var(--sl-color-white);
}
- .top-level > li {
- overflow-wrap: anywhere;
- }
-
.top-level > li + li {
margin-top: 0.75rem;
}9df0e55 to
e2050cd
Compare
e2050cd to
7ff04a4
Compare
7ff04a4 to
55be354
Compare
delucis
left a comment
There was a problem hiding this comment.
Thanks for splitting out that one fix to #814 @julien-deramond!
I think this is looking good if you’d like to go ahead and remove the text strings being used for testing.
55be354 to
f1e175b
Compare
|
55be354 has been removed, and so the a11y tests are back to normal. |
HiDeoo
left a comment
There was a problem hiding this comment.
Just noticed we still need a changeset for the changes.
|
Added a changeset via 47526e2. I supposed it was a "patch" and used a really simple generic sentence. Don't hesitate to update it to change the type of changeset or to enhance the description with more detail if needed. |
delucis
left a comment
There was a problem hiding this comment.
Thanks again for all the hard work chasing down these issues and figuring out the fixes @julien-deramond — and for helping @HiDeoo!
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>





What kind of changes does this PR include?
Before the final merge if/when approved
Description
Closes #754
This PR tackles the main issue from #754 but also tries to tackle #754 (comment). Changes are opinionated and can of course be discussed so that it fits well the global Starlight design and rendering.
The main idea here is to use
overflow-wrap: anywhere.I originally suggested using
overflow-wrap: break-word, butoverflow-wrap: anywhereis a better fit since it doesn't force folks to sometimes force the width of the components when they use it (more info in #756 (comment)).word-break: break-wordis already used in the project but I'd suggest replacing it withoverflow-wrap: anywheresincebreak-wordis deprecated (source: https://developer.mozilla.org/en-US/docs/Web/CSS/word-break#values).This was the main direction. Let's dive into the use cases.
SearchandresetI did not manage to reproduce any issues with or without the original
word-break: break-wordsource code. I've changed it tooverflow-wrap: anywhereas mentioned in the main description for consistency.Badgeoverflow-wrap: anywhereis defined within theBadgecomponent to define the overflow rule whatever the context.PrevNextLinkThis use case will be tackled in a separate PR (https://github.com//pull/814) given its complexity
This one was a bit more complex; unless there's a simpler solution.flex-shrink: 0to the SVG so that its size remains the sameoverflow-wrap: anywhereis added to the<a>s.width: 50%andflex-basis: calc(50% - 1rem)to calculate the right size (and with100%on mobile so that each item takes the full width).No before/after rendering screenshots for this one. You'll find instead the rendering of the different use cases (which have the same layout in responsive):
RightSidebarPanelword-break: break-wordis replaced withoverflow-wrap: anywhere.SidebarSublistAdded a
flex-shrink: 0to the SVG so that its size remains the same and set up a new rule forli(mainly needed for.top-level > li) to useoverflow-wrap: anywhereso that the scope is large enough to cover various use cases within this list.Another use case
While testing everything, if the "On this page" wording is too long, here's the rendering:
I'm not completely sure a fix is needed for this use case. Even with languages containing a lot of characters, the space should be sufficient for normal usage. I don't want to over-engineer it so I'll wait for your thoughts on this one.
Final note
The rendering has been tested on macOS (Firefox, Chrome, and Safari) in responsive mode, with or without long words, and also
tableOfContents: false. There are a lot of use cases so I've probably missed some of them not knowing well Starlight's features.