UNPKG

@astrojs/starlight

Version:

Build beautiful, high-performance documentation websites with Astro

132 lines (114 loc) 4.71 kB
/* How does anchor link placement work? Because anchor links need to placed inline at the end of a heading, but are not children of the heading element itself, positioning them to behave in a desirable way is a tiny bit tricky. Here’s how we do it. 1. We wrap the heading and anchor link in a div and make the heading element inline: <div class="sl-heading-wrapper"> <h2>...</h2><a class="sl-anchor-link">...</a> </a> 2. We need to avoid the anchor link wrapping onto a new line by itself like this because it looks broken: Some heading text ⛓ 3. To achieve this we add an area of padding to the end of the heading and move the link over this padding using negative margin: padding-inline-end creates space at the end of the line ↓ Some heading text[ ]⛓ margin-inline-start then pulls the anchor link into that space ↓ Some heading text[ ⛓ ] This ensures that when the anchor link wraps, the final word in the heading will wrap with it. */ @layer starlight.content { /* ====================================================== WRAPPER ====================================================== */ .sl-markdown-content .sl-heading-wrapper { /* The size of the SVG icon. */ --sl-anchor-icon-size: 0.8275em; /* The horizontal space between the SVG icon and the end of the heading text. */ --sl-anchor-icon-gap: 0.25em; /* The end of line space required to accommodate the anchor link. */ --sl-anchor-icon-space: calc(var(--sl-anchor-icon-size) + var(--sl-anchor-icon-gap)); line-height: var(--sl-line-height-headings); } /* We need to apply the same rule we use for heading spacing to the parent wrapper. */ .sl-markdown-content :not(h1, h2, h3, h4, h5, h6, .sl-heading-wrapper) + :is(.sl-heading-wrapper) { margin-top: 1.5em; } /* These font sizes are set in `markdown.css` for heading elements, but we need them one level higher on the wrapper. */ .sl-markdown-content .sl-heading-wrapper.level-h1 { font-size: var(--sl-text-h1); } .sl-markdown-content .sl-heading-wrapper.level-h2 { font-size: var(--sl-text-h2); } .sl-markdown-content .sl-heading-wrapper.level-h3 { font-size: var(--sl-text-h3); } .sl-markdown-content .sl-heading-wrapper.level-h4 { font-size: var(--sl-text-h4); } .sl-markdown-content .sl-heading-wrapper.level-h5 { font-size: var(--sl-text-h5); } .sl-markdown-content .sl-heading-wrapper.level-h6 { font-size: var(--sl-text-h6); } /* ====================================================== HEADING ====================================================== */ .sl-markdown-content .sl-heading-wrapper > :first-child { display: inline; /* Apply end-of-line padding to the heading element. */ padding-inline-end: var(--sl-anchor-icon-space); } /* ====================================================== LINK ====================================================== */ .sl-markdown-content .sl-anchor-link { position: relative; /* Move the anchor link over the heading element’s end-of-line padding. */ margin-inline-start: calc(-1 * var(--sl-anchor-icon-size)); /* Prevent double or triple clicks from potentially selecting the anchor link a11y text. */ -webkit-user-select: none; user-select: none; /* Prevent double clicks on the last word (or single word) of a heading to include an extra new line in Chrome and Safari. */ display: inline-flex; } /* Increase clickable area for anchor links with a pseudo element that doesn’t impact layout. */ .sl-markdown-content .sl-anchor-link::after { content: ''; position: absolute; /* While most icon spacing is done with `em` to be relative to the heading font-size, increasing the touch area is most important for smaller headings like h5/h6, so we use absolute units, which have a diminishing impact at larger font-sizes. */ inset: -0.25rem -0.5rem; } /* Size and position the SVG icon inside the link. */ .sl-markdown-content .sl-anchor-icon > svg { display: inline; width: var(--sl-anchor-icon-size); /* Center the link icon SVG vertically in the line. */ vertical-align: top; transform: translateY( calc((var(--sl-line-height-headings) * 1em - var(--sl-anchor-icon-size)) / 2) ); } /* On devices with hover capability, hide the anchor link icons and show only show them when focused or when the heading is hovered. */ @media (hover: hover) { .sl-markdown-content .sl-anchor-link { opacity: 0; } .sl-markdown-content .sl-anchor-link:focus, .sl-markdown-content .sl-heading-wrapper:hover .sl-anchor-link { opacity: 1; } } }