mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2026-08-04 11:35:17 -04:00
Refactored CSS, code annotations almost working properly
This commit is contained in:
@@ -47,6 +47,8 @@ export function resetFocusable(
|
||||
el.removeAttribute("tabindex")
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Set scroll lock
|
||||
*
|
||||
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
NEVER,
|
||||
Observable,
|
||||
Subject,
|
||||
combineLatestWith,
|
||||
distinctUntilKeyChanged,
|
||||
finalize,
|
||||
fromEvent,
|
||||
@@ -34,10 +33,23 @@ import {
|
||||
mergeWith,
|
||||
of,
|
||||
switchMap,
|
||||
take,
|
||||
takeWhile,
|
||||
tap,
|
||||
withLatestFrom
|
||||
withLatestFrom,
|
||||
distinctUntilChanged,
|
||||
takeWhile,
|
||||
repeat,
|
||||
EMPTY,
|
||||
observeOn,
|
||||
debounceTime,
|
||||
mapTo,
|
||||
throttle,
|
||||
share,
|
||||
defer,
|
||||
switchMapTo,
|
||||
shareReplay,
|
||||
combineLatest,
|
||||
asapScheduler,
|
||||
animationFrameScheduler
|
||||
} from "rxjs"
|
||||
|
||||
import { feature } from "~/_"
|
||||
@@ -52,7 +64,11 @@ import {
|
||||
getElementSize,
|
||||
getElements,
|
||||
getOptionalElement,
|
||||
watchMedia
|
||||
watchMedia,
|
||||
watchElementContentOffset,
|
||||
watchElementVisibility,
|
||||
getElementOffset,
|
||||
watchElementOffset
|
||||
} from "~/browser"
|
||||
import {
|
||||
renderAnnotation,
|
||||
@@ -69,7 +85,7 @@ import { Component } from "../../_"
|
||||
* Code block
|
||||
*/
|
||||
export interface CodeBlock {
|
||||
scroll: boolean /* Code block overflows */
|
||||
scrollable: boolean /* Code block overflows */
|
||||
annotations?: HTMLElement[] /* Code block annotations */
|
||||
}
|
||||
|
||||
@@ -82,7 +98,7 @@ export interface CodeBlock {
|
||||
*/
|
||||
interface WatchOptions {
|
||||
viewport$: Observable<Viewport> /* Viewport observable */
|
||||
print$: Observable<boolean> /* Print observable */
|
||||
print$: Observable<boolean> /* Media print observable */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +106,8 @@ interface WatchOptions {
|
||||
*/
|
||||
interface MountOptions {
|
||||
viewport$: Observable<Viewport> /* Viewport observable */
|
||||
print$: Observable<boolean> /* Print observable */
|
||||
hover$: Observable<boolean> /* Media hover observable */
|
||||
print$: Observable<boolean> /* Media print observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
@@ -102,6 +119,32 @@ interface MountOptions {
|
||||
*/
|
||||
let index = 0
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Find the code annotations belonging to a code block
|
||||
*
|
||||
* @param el - Code block element
|
||||
*
|
||||
* @returns Code annotations or nothing
|
||||
*/
|
||||
function findAnnotationsList(el: HTMLElement): HTMLElement | undefined {
|
||||
if (el.nextElementSibling) {
|
||||
const sibling = el.nextElementSibling as HTMLElement
|
||||
if (sibling.tagName === "OL")
|
||||
return sibling
|
||||
|
||||
/* Paragraph, may be empty, see https://bit.ly/3r4ZJ2O */
|
||||
else if (sibling.tagName === "P" && !sibling.children.length)
|
||||
return findAnnotationsList(sibling)
|
||||
}
|
||||
|
||||
/* Everything else */
|
||||
return undefined
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
@@ -120,85 +163,168 @@ let index = 0
|
||||
export function watchCodeBlock(
|
||||
el: HTMLElement, { viewport$, print$ }: WatchOptions
|
||||
): Observable<CodeBlock> {
|
||||
const container$ = of(el)
|
||||
|
||||
/* Watch content tabs as they can reveal code blocks */
|
||||
const reveal$ = defer(() => {
|
||||
const container = el.closest("[data-tabs]")
|
||||
if (container instanceof HTMLElement) {
|
||||
return merge(
|
||||
...getElements(":scope > input", container)
|
||||
.map(input => fromEvent(input, "change"))
|
||||
)
|
||||
}
|
||||
return NEVER
|
||||
})
|
||||
|
||||
/* Compute overflow state on resize and content tab change */
|
||||
const scroll$ = viewport$
|
||||
.pipe(
|
||||
switchMap(child => {
|
||||
const container = child.closest("[data-tabs]")
|
||||
if (container instanceof HTMLElement) {
|
||||
return merge(
|
||||
...getElements(":scope > input", container)
|
||||
.map(input => fromEvent(input, "change"))
|
||||
)
|
||||
}
|
||||
return NEVER
|
||||
})
|
||||
distinctUntilKeyChanged("size"),
|
||||
mergeWith(reveal$),
|
||||
map(() => {
|
||||
const visible = getElementSize(el)
|
||||
const content = getElementContentSize(el)
|
||||
return content.width > visible.width
|
||||
}),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
|
||||
/* Transform annotations */
|
||||
const annotations: HTMLElement[] = []
|
||||
const container =
|
||||
el.closest(".highlighttable") ||
|
||||
el.closest(".highlight")
|
||||
if (container) {
|
||||
const list = container.nextElementSibling
|
||||
if (list instanceof HTMLOListElement && (
|
||||
container.classList.contains("annotate") ||
|
||||
feature("content.code.annotate")
|
||||
)) {
|
||||
const items = Array.from(list.children)
|
||||
list.remove()
|
||||
/* Compute content offset of code block */
|
||||
const offset$ = watchElementContentOffset(el)
|
||||
// scroll$
|
||||
// .pipe(
|
||||
// switchMap(scrollable => scrollable
|
||||
// ? watchElementContentOffset(el)
|
||||
// : EMPTY
|
||||
// ),
|
||||
// shareReplay(1) // TBD
|
||||
// )
|
||||
|
||||
/* Replace comments with annotations */
|
||||
for (const comment of getElements(".c, .c1, .cm", el)) {
|
||||
// TODO: from here, annotations #############################################
|
||||
|
||||
/* Split comment at annotations */ // TODO: refactor when revisiting annotations
|
||||
let match: RegExpExecArray | null
|
||||
let text = comment.firstChild as Text
|
||||
do {
|
||||
match = /\((\d+)\)/.exec(text.textContent!)
|
||||
if (match && match.index) {
|
||||
const bubble = text.splitText(match.index)
|
||||
text = bubble.splitText(match[0].length) // complete match length
|
||||
/* Compute whether code annotations must be temporarily hidden */
|
||||
const finish$ = offset$.pipe(debounceTime(125), mapTo(false))
|
||||
const hidden$ = merge(
|
||||
finish$,
|
||||
offset$.pipe(throttle(() => finish$), mapTo(true))
|
||||
)
|
||||
|
||||
const [, j = -1] = match
|
||||
const content = items[+j - 1]
|
||||
if (typeof content !== "undefined") {
|
||||
const annotation = renderAnnotation(+j, content.childNodes)
|
||||
bubble.replaceWith(annotation)
|
||||
annotations.push(annotation)
|
||||
}
|
||||
}
|
||||
} while (match)
|
||||
}
|
||||
|
||||
/* Move elements back on print */ // TODO: refactor memleak (instant loading)
|
||||
print$.subscribe(active => {
|
||||
if (active) {
|
||||
container.insertAdjacentElement("afterend", list)
|
||||
for (const annotation of annotations) {
|
||||
const id = parseInt(annotation.getAttribute("data-index")!, 10)
|
||||
const typeset = getOptionalElement(":scope .md-typeset", annotation)!
|
||||
items[id - 1].append(...Array.from(typeset.childNodes))
|
||||
}
|
||||
} else {
|
||||
list.remove()
|
||||
for (const annotation of annotations) {
|
||||
const id = parseInt(annotation.getAttribute("data-index")!, 10)
|
||||
const nodes = items[id - 1].childNodes
|
||||
getElement(":scope .md-typeset", annotation)
|
||||
.append(...Array.from(nodes))
|
||||
}
|
||||
}
|
||||
})
|
||||
/* Hide tooltip while scrolling */
|
||||
hidden$.subscribe(hidden => {
|
||||
if (hidden) {
|
||||
console.log("scrolling...")
|
||||
// el.setAttribute("data-md-state", "scroll")
|
||||
} else {
|
||||
console.log("scrolling done")
|
||||
el.removeAttribute("data-md-state")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const annotations$ = defer(() => {
|
||||
const annotations: HTMLElement[] = []
|
||||
|
||||
/* */
|
||||
const container = el.closest(".highlighttable") || el.closest(".highlight")
|
||||
if (!(container instanceof HTMLElement))
|
||||
return NEVER
|
||||
|
||||
/* */
|
||||
if (container instanceof HTMLElement) {
|
||||
const list = findAnnotationsList(container)
|
||||
if (typeof list !== "undefined" && (
|
||||
container.classList.contains("annotate") ||
|
||||
feature("content.code.annotate")
|
||||
)) {
|
||||
|
||||
/* Replace comments with annotations */
|
||||
const items = getElements(":scope > li", list)
|
||||
for (const comment of getElements(".c, .c1, .cm", el)) {
|
||||
|
||||
/* Split comment at annotations */ // TODO: refactor when revisiting annotations
|
||||
let match: RegExpExecArray | null
|
||||
let text = comment.firstChild as Text
|
||||
do {
|
||||
match = /\((\d+)\)/.exec(text.textContent!)
|
||||
if (match && match.index) {
|
||||
const bubble = text.splitText(match.index)
|
||||
text = bubble.splitText(match[0].length) // complete match length
|
||||
|
||||
const [, j = -1] = match
|
||||
const content = items[+j - 1]
|
||||
if (typeof content !== "undefined") {
|
||||
const annotation = renderAnnotation(+j, content.childNodes)
|
||||
bubble.replaceWith(annotation) // bubble is and will stay replaced...
|
||||
annotations.push(annotation)
|
||||
}
|
||||
}
|
||||
} while (match)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // offset, compute tooltip position...
|
||||
// offset$.subscribe(({ x }) => {
|
||||
// el.style.setProperty("--md-tooltip-x", `${x}px`)
|
||||
// })
|
||||
|
||||
// wrong, we must always recompute the position..
|
||||
for (const annotation of annotations) {
|
||||
const size = getElementSize(annotation)
|
||||
offset$
|
||||
.pipe(
|
||||
// observeOn(animationFrameScheduler), // TODO: ?
|
||||
withLatestFrom(watchElementOffset(annotation)),
|
||||
map(([scroll, offset]) => {
|
||||
|
||||
// if left is clamped, we must add to top!
|
||||
// TODO: this must also be placed here!
|
||||
annotation.style.setProperty(
|
||||
"--md-tooltip-x", `${offset.x - scroll.x}px`
|
||||
)
|
||||
annotation.style.setProperty(
|
||||
"--md-tooltip-y", `${offset.y - scroll.y}px`
|
||||
)
|
||||
})
|
||||
)
|
||||
.subscribe()
|
||||
|
||||
|
||||
}
|
||||
|
||||
return of(annotations)
|
||||
})
|
||||
|
||||
// // /* Move elements back on print */ // TODO: refactor memleak (instant loading)
|
||||
// // print$.subscribe(active => {
|
||||
// // if (active) {
|
||||
// // container.insertAdjacentElement("afterend", list)
|
||||
// // for (const annotation of annotations) {
|
||||
// // const id = parseInt(annotation.getAttribute("data-index")!, 10)
|
||||
// // const typeset = getOptionalElement(":scope .md-typeset", annotation)!
|
||||
// // items[id - 1].append(...Array.from(typeset.childNodes))
|
||||
// // }
|
||||
// // } else {
|
||||
// // list.remove()
|
||||
// // for (const annotation of annotations) {
|
||||
// // const id = parseInt(annotation.getAttribute("data-index")!, 10)
|
||||
// // const nodes = items[id - 1].childNodes
|
||||
// // getElement(":scope .md-typeset", annotation)
|
||||
// // .append(...Array.from(nodes))
|
||||
// // }
|
||||
// // }
|
||||
// // })
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
/* Check overflow on resize and tab change */
|
||||
return viewport$
|
||||
.pipe(
|
||||
distinctUntilKeyChanged("size"),
|
||||
mergeWith(container$),
|
||||
map(() => {
|
||||
mergeWith(reveal$),
|
||||
switchMapTo(annotations$),
|
||||
map(annotations => {
|
||||
const visible = getElementSize(el)
|
||||
const content = getElementContentSize(el)
|
||||
return {
|
||||
@@ -222,43 +348,55 @@ export function watchCodeBlock(
|
||||
* @returns Code block component observable
|
||||
*/
|
||||
export function mountCodeBlock(
|
||||
el: HTMLElement, options: MountOptions
|
||||
el: HTMLElement, { hover$, ...options }: MountOptions
|
||||
): Observable<Component<CodeBlock>> {
|
||||
const internal$ = new Subject<CodeBlock>()
|
||||
internal$
|
||||
.pipe(
|
||||
withLatestFrom(watchMedia("(hover)"))
|
||||
withLatestFrom(hover$)
|
||||
)
|
||||
.subscribe(([{ scroll }, hover]) => {
|
||||
.subscribe(([{ scrollable: scroll }, hover]) => {
|
||||
if (scroll && hover)
|
||||
setFocusable(el)
|
||||
else
|
||||
resetFocusable(el)
|
||||
})
|
||||
|
||||
/* Compute annotation position */
|
||||
internal$
|
||||
.pipe(
|
||||
take(1),
|
||||
takeWhile(({ annotations }) => !!annotations?.length),
|
||||
map(({ annotations }) => annotations!
|
||||
.map(annotation => getElement(".md-tooltip", annotation))
|
||||
),
|
||||
combineLatestWith(viewport$
|
||||
.pipe(
|
||||
distinctUntilKeyChanged("size")
|
||||
)
|
||||
)
|
||||
)
|
||||
.subscribe(([tooltips, { size }]) => {
|
||||
for (const tooltip of tooltips) {
|
||||
const { x, width } = tooltip.getBoundingClientRect()
|
||||
if (x + width > size.width)
|
||||
tooltip.classList.add("md-tooltip--end")
|
||||
else
|
||||
tooltip.classList.remove("md-tooltip--end")
|
||||
}
|
||||
})
|
||||
// /* Compute annotation position */
|
||||
// internal$
|
||||
// .pipe(
|
||||
// take(1),
|
||||
// takeWhile(({ annotations }) => !!annotations?.length),
|
||||
// combineLatestWith(viewport$
|
||||
// .pipe(
|
||||
// distinctUntilKeyChanged("size")
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// .subscribe(([{ annotations }, { size }]) => {
|
||||
// if (typeof annotations === "undefined")
|
||||
// return
|
||||
|
||||
// /* Compute annotation positions */
|
||||
// for (const annotation of annotations) {
|
||||
// const annotationIndex = getElement(".md-annotation__index", annotation)
|
||||
// const tooltip = getElement(".md-tooltip", annotation)
|
||||
// console.log(annotationIndex, tooltip)
|
||||
|
||||
// const { x } = getElementOffset(annotationIndex)
|
||||
|
||||
// console.log(x)
|
||||
|
||||
// }
|
||||
// // console.log(tooltips, size)
|
||||
// // for (const tooltip of tooltips) {
|
||||
// // const { x, width } = tooltip.getBoundingClientRect()
|
||||
// // if (x + width > size.width)
|
||||
// // tooltip.classList.add("md-tooltip--end")
|
||||
// // else
|
||||
// // tooltip.classList.remove("md-tooltip--end")
|
||||
// // }
|
||||
// })
|
||||
|
||||
/* Render button for Clipboard.js integration */
|
||||
if (ClipboardJS.isSupported()) {
|
||||
|
||||
@@ -39,7 +39,7 @@ export function renderAnnotation(
|
||||
): HTMLElement {
|
||||
return (
|
||||
<aside class="md-annotation" data-index={id} tabIndex={0}>
|
||||
<div class="md-tooltip">
|
||||
<div class="md-annotation__inner md-tooltip">
|
||||
<div class="md-tooltip__inner md-typeset">
|
||||
{...Array.from(content)}
|
||||
</div>
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
@import "main/layout/clipboard";
|
||||
@import "main/layout/content";
|
||||
@import "main/layout/dialog";
|
||||
@import "main/layout/footer";
|
||||
@import "main/layout/form";
|
||||
@import "main/layout/header";
|
||||
@import "main/layout/footer";
|
||||
@import "main/layout/nav";
|
||||
@import "main/layout/search";
|
||||
@import "main/layout/select";
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Color definitions
|
||||
// Color variables
|
||||
:root {
|
||||
|
||||
// Default color shades
|
||||
|
||||
@@ -61,7 +61,7 @@ kbd {
|
||||
// Rules: typesetted content
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Icon definitions
|
||||
// General variables
|
||||
:root {
|
||||
--md-typeset-table-sort-icon: svg-load("material/sort.svg");
|
||||
--md-typeset-table-sort-icon--asc: svg-load("material/sort-ascending.svg");
|
||||
@@ -84,12 +84,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Default spacing
|
||||
ul,
|
||||
ol,
|
||||
dl,
|
||||
figure,
|
||||
blockquote,
|
||||
pre {
|
||||
:is(ul, ol, dl, figure, blockquote, pre) {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
@@ -134,8 +129,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Headline on level 5-6
|
||||
h5,
|
||||
h6 {
|
||||
:is(h5, h6) {
|
||||
margin: px2em(16px, 12.8px) 0;
|
||||
color: var(--md-default-fg-color--light);
|
||||
font-weight: 700;
|
||||
@@ -167,8 +161,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Text link on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
color: var(--md-accent-fg-color);
|
||||
}
|
||||
|
||||
@@ -180,9 +173,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Code block
|
||||
code,
|
||||
pre,
|
||||
kbd {
|
||||
:is(code, pre, kbd) {
|
||||
color: var(--md-code-fg-color);
|
||||
direction: ltr;
|
||||
|
||||
@@ -209,12 +200,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Code block in headline
|
||||
h1 code,
|
||||
h2 code,
|
||||
h3 code,
|
||||
h4 code,
|
||||
h5 code,
|
||||
h6 code {
|
||||
:is(h1, h2, h3, h4, h5, h6) code {
|
||||
margin: initial;
|
||||
padding: initial;
|
||||
background-color: transparent;
|
||||
@@ -239,6 +225,7 @@ kbd {
|
||||
padding: px2em(10.5px, 13.6px) px2em(16px, 13.6px);
|
||||
overflow: auto;
|
||||
word-break: normal;
|
||||
outline-color: var(--md-accent-fg-color);
|
||||
box-shadow: none;
|
||||
box-decoration-break: slice;
|
||||
touch-action: auto;
|
||||
@@ -268,20 +255,6 @@ kbd {
|
||||
}
|
||||
}
|
||||
|
||||
// [mobile -]: Align with body copy
|
||||
@include break-to-device(mobile) {
|
||||
|
||||
// Unformatted text
|
||||
> pre {
|
||||
margin: 1em px2rem(-16px);
|
||||
|
||||
// Code block
|
||||
code {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Keyboard key
|
||||
kbd {
|
||||
display: inline-block;
|
||||
@@ -317,8 +290,7 @@ kbd {
|
||||
position: relative;
|
||||
|
||||
// Tooltip
|
||||
&[title]:focus::after,
|
||||
&[title]:hover::after {
|
||||
&[title]:is(:focus, :hover)::after {
|
||||
@include z-depth(2);
|
||||
|
||||
position: absolute;
|
||||
@@ -344,8 +316,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Superscript and subscript
|
||||
sup,
|
||||
sub {
|
||||
:is(sup, sub) {
|
||||
margin-left: px2em(1px, 12.8px);
|
||||
|
||||
// Adjust for right-to-left languages
|
||||
@@ -376,8 +347,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Unordered and ordered list
|
||||
ul,
|
||||
ol {
|
||||
:is(ul, ol) {
|
||||
display: flow-root;
|
||||
margin-left: px2em(10px);
|
||||
padding: 0;
|
||||
@@ -410,8 +380,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Adjust spacing
|
||||
p,
|
||||
blockquote {
|
||||
:is(p, blockquote) {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
@@ -421,8 +390,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Nested list
|
||||
ul,
|
||||
ol {
|
||||
:is(ul, ol) {
|
||||
margin: 0.5em 0 0.5em px2em(10px);
|
||||
|
||||
// Adjust for right-to-left languages
|
||||
@@ -446,8 +414,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Image or icon
|
||||
img,
|
||||
svg {
|
||||
:is(img, svg) {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
|
||||
@@ -519,8 +486,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Elements in table heading and cell
|
||||
th > *,
|
||||
td > * {
|
||||
:is(th, td) > * {
|
||||
|
||||
// Adjust spacing on first child
|
||||
&:first-child {
|
||||
@@ -534,8 +500,7 @@ kbd {
|
||||
}
|
||||
|
||||
// Table heading and cell
|
||||
th:not([align]),
|
||||
td:not([align]) {
|
||||
:is(th, td):not([align]) {
|
||||
text-align: left;
|
||||
|
||||
// Adjust for right-to-left languages
|
||||
@@ -644,3 +609,21 @@ kbd {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Rules: top-level
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// [mobile -]: Align with body copy
|
||||
@include break-to-device(mobile) {
|
||||
|
||||
// Top-level unformatted content
|
||||
.md-content__inner > pre {
|
||||
margin: 1em px2rem(-16px);
|
||||
|
||||
// Code block
|
||||
code {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ $admonitions: (
|
||||
// Rules: layout
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Icon definitions
|
||||
// Admonition variables
|
||||
:root {
|
||||
@each $names, $props in $admonitions {
|
||||
--md-admonition-icon--#{nth($names, 1)}:
|
||||
@@ -60,8 +60,8 @@ $admonitions: (
|
||||
// Scoped in typesetted content to match specificity of regular content
|
||||
.md-typeset {
|
||||
|
||||
// Admonition
|
||||
.admonition {
|
||||
// Admonition and Details
|
||||
:is(.admonition, details) {
|
||||
display: flow-root;
|
||||
margin: px2em(20px, 12.8px) 0;
|
||||
padding: 0 px2rem(12px);
|
||||
@@ -87,7 +87,7 @@ $admonitions: (
|
||||
}
|
||||
|
||||
// Adjust vertical spacing for nested admonitions
|
||||
.admonition {
|
||||
:is(.admonition, details) {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
@@ -114,7 +114,7 @@ $admonitions: (
|
||||
}
|
||||
|
||||
// Admonition title
|
||||
.admonition-title {
|
||||
:is(.admonition-title, summary) {
|
||||
position: relative;
|
||||
margin: 0 px2rem(-12px) 0 px2rem(-16px);
|
||||
padding: px2rem(8px) px2rem(12px) px2rem(8px) px2rem(40px);
|
||||
@@ -165,13 +165,19 @@ $admonitions: (
|
||||
$name: list.nth($names, 1);
|
||||
$tint: list.nth($props, 2);
|
||||
|
||||
// Admonition flavour selectors
|
||||
$flavours: ();
|
||||
@each $name in $names {
|
||||
$flavours: list.join($flavours, ".#{$name}", $separator: comma);
|
||||
}
|
||||
|
||||
// Admonition flavour
|
||||
.md-typeset .admonition.#{$name} {
|
||||
.md-typeset :is(.admonition, details):is(#{$flavours}) {
|
||||
border-color: $tint;
|
||||
}
|
||||
|
||||
// Admonition flavour title
|
||||
.md-typeset .#{$name} > .admonition-title {
|
||||
.md-typeset :is(#{$flavours}) > :is(.admonition-title, summary) {
|
||||
background-color: color.adjust($tint, $alpha: -0.9);
|
||||
border-color: $tint;
|
||||
|
||||
@@ -183,13 +189,4 @@ $admonitions: (
|
||||
mask-size: contain;
|
||||
}
|
||||
}
|
||||
|
||||
// Define synonyms for flavours
|
||||
@if length($names) > 1 {
|
||||
@for $n from 2 through length($names) {
|
||||
.#{nth($names, $n)} {
|
||||
@extend .#{$name};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Icon definitions
|
||||
// Footnotes variables
|
||||
:root {
|
||||
--md-footnotes-icon: svg-load("material/keyboard-return.svg");
|
||||
}
|
||||
@@ -61,8 +61,7 @@
|
||||
}
|
||||
|
||||
// Show backreferences on footnote hover/target
|
||||
&:hover .footnote-backref,
|
||||
&:target .footnote-backref {
|
||||
&:is(:hover, :target) .footnote-backref {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -50,8 +50,7 @@
|
||||
}
|
||||
|
||||
// Show headerlinks on parent hover
|
||||
:hover > .headerlink,
|
||||
:target > .headerlink,
|
||||
:is(:hover, :target) > .headerlink,
|
||||
.headerlink:focus {
|
||||
opacity: 1;
|
||||
transition:
|
||||
@@ -61,8 +60,7 @@
|
||||
|
||||
// Adjust color on parent target or focus/hover
|
||||
:target > .headerlink,
|
||||
.headerlink:focus,
|
||||
.headerlink:hover {
|
||||
.headerlink:is(:focus, :hover) {
|
||||
color: var(--md-accent-fg-color);
|
||||
}
|
||||
|
||||
@@ -84,9 +82,7 @@
|
||||
}
|
||||
|
||||
// Adjust scroll offset for headlines of level 1-3
|
||||
h1:target,
|
||||
h2:target,
|
||||
h3:target {
|
||||
:is(h1, h2, h3):target {
|
||||
scroll-margin-top: initial;
|
||||
|
||||
// Anchor correction hack
|
||||
@@ -142,8 +138,7 @@
|
||||
}
|
||||
|
||||
// Adjust scroll offset for headlines of level 5-6
|
||||
h5:target,
|
||||
h6:target {
|
||||
:is(h5, h6):target {
|
||||
scroll-margin-top: initial;
|
||||
|
||||
// Anchor correction hack
|
||||
|
||||
@@ -28,9 +28,7 @@
|
||||
.md-typeset {
|
||||
|
||||
// Deletion, addition or comment
|
||||
del.critic,
|
||||
ins.critic,
|
||||
.critic.comment {
|
||||
:is(del, ins, .comment).critic {
|
||||
box-decoration-break: clone;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Icon definitions
|
||||
// Details variables
|
||||
:root {
|
||||
--md-details-icon: svg-load("material/chevron-right.svg");
|
||||
}
|
||||
@@ -36,8 +36,6 @@
|
||||
|
||||
// Details
|
||||
details {
|
||||
@extend .admonition;
|
||||
|
||||
display: flow-root;
|
||||
padding-top: 0;
|
||||
overflow: visible;
|
||||
@@ -64,8 +62,6 @@
|
||||
|
||||
// Details title
|
||||
summary {
|
||||
@extend .admonition-title;
|
||||
|
||||
display: block;
|
||||
min-height: px2rem(20px);
|
||||
padding: px2rem(8px) px2rem(36px) px2rem(8px) px2rem(40px);
|
||||
@@ -114,8 +110,7 @@
|
||||
}
|
||||
|
||||
// Hide native details marker
|
||||
&::marker,
|
||||
&::-webkit-details-marker {
|
||||
&:is(::marker, ::-webkit-details-marker) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,7 @@
|
||||
.md-typeset {
|
||||
|
||||
// Emoji and icon container
|
||||
.emojione,
|
||||
.twemoji,
|
||||
.gemoji {
|
||||
:is(.emojione, .twemoji, .gemoji) {
|
||||
display: inline-flex;
|
||||
height: px2em(18px);
|
||||
vertical-align: text-top;
|
||||
|
||||
@@ -26,8 +26,10 @@
|
||||
|
||||
// Code block
|
||||
.highlight {
|
||||
.o, // Operator
|
||||
.ow { // Operator, word
|
||||
|
||||
// .o = Operator
|
||||
// .ow = Operator, word
|
||||
:is(.o, .ow) {
|
||||
color: var(--md-code-hl-operator-color);
|
||||
}
|
||||
|
||||
@@ -35,100 +37,112 @@
|
||||
color: var(--md-code-hl-punctuation-color);
|
||||
}
|
||||
|
||||
.cpf, // Comment, preprocessor file
|
||||
.l, // Literal
|
||||
.s, // Literal, string
|
||||
.sb, // Literal, string backticks
|
||||
.sc, // Literal, string char
|
||||
.s2, // Literal, string double
|
||||
.si, // Literal, string interpol
|
||||
.s1, // Literal, string single
|
||||
.ss { // Literal, string symbol
|
||||
// .cpf = Comment, preprocessor file
|
||||
// .l = Literal
|
||||
// .s = Literal, string
|
||||
// .sb = Literal, string backticks
|
||||
// .sc = Literal, string char
|
||||
// .s2 = Literal, string double
|
||||
// .si = Literal, string interpol
|
||||
// .s1 = Literal, string single
|
||||
// .ss = Literal, string symbol
|
||||
:is(.cpf, .l, .s, .sb, .sc, .s2, .si, .s1, .ss) {
|
||||
color: var(--md-code-hl-string-color);
|
||||
}
|
||||
|
||||
.cp, // Comment, pre-processor
|
||||
.se, // Literal, string escape
|
||||
.sh, // Literal, string heredoc
|
||||
.sr, // Literal, string regex
|
||||
.sx { // Literal, string other
|
||||
// .cp = Comment, pre-processor
|
||||
// .se = Literal, string escape
|
||||
// .sh = Literal, string heredoc
|
||||
// .sr = Literal, string regex
|
||||
// .sx = Literal, string other
|
||||
:is(.cp, .se, .sh, .sr, .sx) {
|
||||
color: var(--md-code-hl-special-color);
|
||||
}
|
||||
|
||||
.m, // Number
|
||||
.mb, // Number, binary
|
||||
.mf, // Number, float
|
||||
.mh, // Number, hex
|
||||
.mi, // Number, integer
|
||||
.il, // Number, integer long
|
||||
.mo { // Number, octal
|
||||
// .m = Number
|
||||
// .mb = Number, binary
|
||||
// .mf = Number, float
|
||||
// .mh = Number, hex
|
||||
// .mi = Number, integer
|
||||
// .il = Number, integer long
|
||||
// .mo = Number, octal
|
||||
:is(.m, .mb, .mf, .mh, .mi, .il, .mo) {
|
||||
color: var(--md-code-hl-number-color);
|
||||
}
|
||||
|
||||
.k, // Keyword,
|
||||
.kd, // Keyword, declaration
|
||||
.kn, // Keyword, namespace
|
||||
.kp, // Keyword, pseudo
|
||||
.kr, // Keyword, reserved
|
||||
.kt { // Keyword, type
|
||||
// .k = Keyword,
|
||||
// .kd = Keyword, declaration
|
||||
// .kn = Keyword, namespace
|
||||
// .kp = Keyword, pseudo
|
||||
// .kr = Keyword, reserved
|
||||
// .kt = Keyword, type
|
||||
:is(.k, .kd, .kn, .kp, .kr, .kt) {
|
||||
color: var(--md-code-hl-keyword-color);
|
||||
}
|
||||
|
||||
.kc, // Keyword, constant
|
||||
.n { // Name
|
||||
// .kc = Keyword, constant
|
||||
// .n = Name
|
||||
:is(.kc, .n) {
|
||||
color: var(--md-code-hl-name-color);
|
||||
}
|
||||
|
||||
.no, // Name, constant
|
||||
.nb, // Name, builtin
|
||||
.bp { // Name, builtin pseudo
|
||||
// .no = Name, constant
|
||||
// .nb = Name, builtin
|
||||
// .bp = Name, builtin pseudo
|
||||
:is(.no, .nb, .bp) {
|
||||
color: var(--md-code-hl-constant-color);
|
||||
}
|
||||
|
||||
.nc, // Name, class
|
||||
.ne, // Name, exception
|
||||
.nf, // Name, function
|
||||
.nn { // Name, namespace
|
||||
// .nc = Name, class
|
||||
// .ne = Name, exception
|
||||
// .nf = Name, function
|
||||
// .nn = Name, namespace
|
||||
:is(.nc, .ne, .nf, .nn) {
|
||||
color: var(--md-code-hl-function-color);
|
||||
}
|
||||
|
||||
.nd, // Name, decorator
|
||||
.ni, // Name, entity
|
||||
.nl, // Name, label
|
||||
.nt { // Name, tag
|
||||
// .nd = Name, decorator
|
||||
// .ni = Name, entity
|
||||
// .nl = Name, label
|
||||
// .nt = Name, tag
|
||||
:is(.nd, .ni, .nl, .nt) {
|
||||
color: var(--md-code-hl-keyword-color);
|
||||
}
|
||||
|
||||
.c, // Comment
|
||||
.cm, // Comment, multiline
|
||||
.c1, // Comment, single
|
||||
.ch, // Comment, shebang
|
||||
.cs, // Comment, special
|
||||
.sd { // Literal, string doc
|
||||
// .c = Comment
|
||||
// .cm = Comment, multiline
|
||||
// .c1 = Comment, single
|
||||
// .ch = Comment, shebang
|
||||
// .cs = Comment, special
|
||||
// .sd = Literal, string doc
|
||||
:is(.c, .cm, .c1, .ch, .cs, .sd) {
|
||||
color: var(--md-code-hl-comment-color);
|
||||
}
|
||||
|
||||
.na, // Name, attribute
|
||||
.nv, // Variable,
|
||||
.vc, // Variable, class
|
||||
.vg, // Variable, global
|
||||
.vi { // Variable, instance
|
||||
// .na = Name, attribute
|
||||
// .nv = Variable,
|
||||
// .vc = Variable, class
|
||||
// .vg = Variable, global
|
||||
// .vi = Variable, instance
|
||||
:is(.na, .nv, .vc, .vg, .vi) {
|
||||
color: var(--md-code-hl-variable-color);
|
||||
}
|
||||
|
||||
.ge, // Generic, emph
|
||||
.gr, // Generic, error
|
||||
.gh, // Generic, heading
|
||||
.go, // Generic, output
|
||||
.gp, // Generic, prompt
|
||||
.gs, // Generic, strong
|
||||
.gu, // Generic, subheading
|
||||
.gt { // Generic, traceback
|
||||
// .ge = Generic, emph
|
||||
// .gr = Generic, error
|
||||
// .gh = Generic, heading
|
||||
// .go = Generic, output
|
||||
// .gp = Generic, prompt
|
||||
// .gs = Generic, strong
|
||||
// .gu = Generic, subheading
|
||||
// .gt = Generic, traceback
|
||||
:is(.ge, .gr, .gh, .go, .gp, .gs, .gu, .gt) {
|
||||
color: var(--md-code-hl-generic-color);
|
||||
}
|
||||
|
||||
.gd, // Diff, delete
|
||||
.gi { // Diff, insert
|
||||
// .gd = Diff, delete
|
||||
// .gi = Diff, insert
|
||||
:is(.gd, .gi) {
|
||||
margin: 0 px2em(-2px);
|
||||
padding: 0 px2em(2px);
|
||||
border-radius: px2rem(2px);
|
||||
@@ -198,8 +212,7 @@
|
||||
|
||||
// Set table elements to block layout, because otherwise the whole flexbox
|
||||
// hacking won't work correctly
|
||||
tbody,
|
||||
td {
|
||||
:is(tbody, td) {
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
@@ -270,36 +283,40 @@
|
||||
border-bottom-right-radius: px2rem(2px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [mobile -]: Align with body copy
|
||||
@include break-to-device(mobile) {
|
||||
// ----------------------------------------------------------------------------
|
||||
// Rules: top-level
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Top-level code block
|
||||
&.md-content__inner > .highlight {
|
||||
margin: 1em px2rem(-16px);
|
||||
// [mobile -]: Align with body copy
|
||||
@include break-to-device(mobile) {
|
||||
|
||||
// Highlighted line
|
||||
.hll {
|
||||
margin: 0 px2rem(-16px);
|
||||
padding: 0 px2rem(16px);
|
||||
}
|
||||
// Top-level code block
|
||||
.md-content__inner > .highlight {
|
||||
margin: 1em px2rem(-16px);
|
||||
|
||||
// Omit rounded borders
|
||||
code {
|
||||
border-radius: 0;
|
||||
}
|
||||
// Highlighted line
|
||||
.hll {
|
||||
margin: 0 px2rem(-16px);
|
||||
padding: 0 px2rem(16px);
|
||||
}
|
||||
|
||||
// Top-level code block with line numbers
|
||||
&.md-content__inner > > .highlighttable {
|
||||
margin: 1em px2rem(-16px);
|
||||
// Omit rounded borders
|
||||
code {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Highlighted line
|
||||
.hll {
|
||||
margin: 0 px2rem(-16px);
|
||||
padding: 0 px2rem(16px);
|
||||
}
|
||||
// Top-level code block with line numbers
|
||||
.md-content__inner > .highlighttable {
|
||||
margin: 1em px2rem(-16px);
|
||||
border-radius: 0;
|
||||
|
||||
// Highlighted line
|
||||
.hll {
|
||||
margin: 0 px2rem(-16px);
|
||||
padding: 0 px2rem(16px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
.keys {
|
||||
|
||||
// Keyboard key icon
|
||||
kbd::before,
|
||||
kbd::after {
|
||||
kbd:is(::before, ::after) {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
color: inherit;
|
||||
|
||||
@@ -129,39 +129,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// [mobile -]: Align with body copy
|
||||
@include break-to-device(mobile) {
|
||||
|
||||
// Top-level tabbed labels
|
||||
> .tabbed-set .tabbed-labels {
|
||||
max-width: 100vw;
|
||||
margin: 0 px2rem(-16px);
|
||||
padding-left: px2rem(16px);
|
||||
scroll-padding-left: px2rem(16px);
|
||||
|
||||
// Adjust for right-to-left languages
|
||||
[dir="rtl"] & {
|
||||
padding-right: px2rem(16px);
|
||||
padding-left: initial;
|
||||
scroll-padding-right: px2rem(16px);
|
||||
scroll-padding-left: initial;
|
||||
}
|
||||
|
||||
// Hack: some browsers ignore the right padding on flex containers,
|
||||
// see https://bit.ly/3lsPS3S
|
||||
&::after {
|
||||
padding-right: px2rem(16px);
|
||||
content: "";
|
||||
|
||||
// Adjust for right-to-left languages
|
||||
[dir="rtl"] & {
|
||||
padding-right: initial;
|
||||
padding-left: px2rem(16px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tabbed content
|
||||
.tabbed-content {
|
||||
width: 100%;
|
||||
@@ -228,6 +195,43 @@
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Rules: top-level
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// [mobile -]: Align with body copy
|
||||
@include break-to-device(mobile) {
|
||||
|
||||
// Top-level tabbed labels
|
||||
.md-content__inner > .tabbed-set .tabbed-labels {
|
||||
max-width: 100vw;
|
||||
margin: 0 px2rem(-16px);
|
||||
padding-left: px2rem(16px);
|
||||
scroll-padding-left: px2rem(16px);
|
||||
|
||||
// Adjust for right-to-left languages
|
||||
[dir="rtl"] & {
|
||||
padding-right: px2rem(16px);
|
||||
padding-left: initial;
|
||||
scroll-padding-right: px2rem(16px);
|
||||
scroll-padding-left: initial;
|
||||
}
|
||||
|
||||
// Hack: some browsers ignore the right padding on flex containers,
|
||||
// see https://bit.ly/3lsPS3S
|
||||
&::after {
|
||||
padding-right: px2rem(16px);
|
||||
content: "";
|
||||
|
||||
// Adjust for right-to-left languages
|
||||
[dir="rtl"] & {
|
||||
padding-right: initial;
|
||||
padding-left: px2rem(16px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Placeholders: improve colocation for better compression
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Icon definitions
|
||||
// Tasklist variables
|
||||
:root {
|
||||
--md-tasklist-icon:
|
||||
svg-load("octicons/check-circle-fill-24.svg");
|
||||
|
||||
@@ -24,14 +24,14 @@
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Icon definitions
|
||||
// Clipboard button variables
|
||||
:root {
|
||||
--md-clipboard-icon: svg-load("material/content-copy.svg");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Button to copy to clipboard
|
||||
// Clipboard button
|
||||
.md-clipboard {
|
||||
position: absolute;
|
||||
top: px2em(8px);
|
||||
@@ -63,8 +63,7 @@
|
||||
}
|
||||
|
||||
// Button on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
color: var(--md-accent-fg-color);
|
||||
}
|
||||
|
||||
@@ -82,7 +81,7 @@
|
||||
content: "";
|
||||
}
|
||||
|
||||
// Inline button
|
||||
// Inline clipboard button
|
||||
&--inline {
|
||||
cursor: pointer;
|
||||
|
||||
@@ -94,8 +93,7 @@
|
||||
}
|
||||
|
||||
// Code block on focus/hover
|
||||
&:focus code,
|
||||
&:hover code {
|
||||
&:is(:focus, :hover) code {
|
||||
color: var(--md-accent-fg-color);
|
||||
background-color: var(--md-accent-fg-color--transparent);
|
||||
}
|
||||
|
||||
@@ -54,8 +54,7 @@
|
||||
}
|
||||
|
||||
// Footer link on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
@@ -152,8 +151,7 @@
|
||||
color: var(--md-footer-fg-color--light);
|
||||
|
||||
// Text link on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
color: var(--md-footer-fg-color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +49,7 @@
|
||||
}
|
||||
|
||||
// Button on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
color: var(--md-accent-bg-color);
|
||||
background-color: var(--md-accent-fg-color);
|
||||
border-color: var(--md-accent-fg-color);
|
||||
@@ -69,8 +68,7 @@
|
||||
transition: box-shadow 250ms;
|
||||
|
||||
// Input on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
box-shadow:
|
||||
0 px2rem(8px) px2rem(20px) hsla(0, 0%, 0%, 0.15),
|
||||
0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.15);
|
||||
|
||||
@@ -109,8 +109,7 @@
|
||||
}
|
||||
|
||||
// Image or icon
|
||||
img,
|
||||
svg {
|
||||
:is(img, svg) {
|
||||
display: block;
|
||||
width: px2rem(24px);
|
||||
height: px2rem(24px);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Icon definitions
|
||||
// Navigation variables
|
||||
:root {
|
||||
--md-nav-icon--prev: svg-load("material/arrow-left.svg");
|
||||
--md-nav-icon--next: svg-load("material/chevron-right.svg");
|
||||
@@ -60,8 +60,7 @@
|
||||
&.md-logo {
|
||||
|
||||
// Image or icon
|
||||
img,
|
||||
svg {
|
||||
:is(img, svg) {
|
||||
display: block;
|
||||
width: px2rem(48px);
|
||||
height: px2rem(48px);
|
||||
@@ -122,8 +121,7 @@
|
||||
}
|
||||
|
||||
// Navigation link on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
color: var(--md-accent-fg-color);
|
||||
}
|
||||
|
||||
@@ -185,8 +183,7 @@
|
||||
&--primary {
|
||||
|
||||
// Navigation title and item
|
||||
.md-nav__title,
|
||||
.md-nav__item {
|
||||
:is(.md-nav__title, .md-nav__item) {
|
||||
font-size: px2rem(16px);
|
||||
line-height: 1.5;
|
||||
}
|
||||
@@ -285,8 +282,7 @@
|
||||
color: var(--md-typeset-a-color);
|
||||
|
||||
// Navigation link on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
color: var(--md-accent-fg-color);
|
||||
}
|
||||
}
|
||||
@@ -523,8 +519,7 @@
|
||||
}
|
||||
|
||||
// Show nested navigation when toggle is active or indeterminate
|
||||
&__toggle:checked ~ &,
|
||||
&__toggle:indeterminate ~ & {
|
||||
&__toggle:is(:checked, :indeterminate) ~ & {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Icon definitions
|
||||
// Search variables
|
||||
:root {
|
||||
--md-search-result-icon: svg-load("material/file-search-outline.svg");
|
||||
}
|
||||
@@ -613,8 +613,7 @@
|
||||
scroll-snap-align: start;
|
||||
|
||||
// Search result link on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
background-color: var(--md-accent-fg-color--transparent);
|
||||
}
|
||||
|
||||
@@ -649,8 +648,7 @@
|
||||
}
|
||||
|
||||
// Search result more link on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
color: var(--md-accent-fg-color);
|
||||
background-color: var(--md-accent-fg-color--transparent);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
// Selection bubble
|
||||
// Selection tooltip
|
||||
&__inner {
|
||||
position: absolute;
|
||||
top: calc(100% - #{px2rem(4px)});
|
||||
@@ -50,8 +50,7 @@
|
||||
max-height 0ms 500ms;
|
||||
|
||||
// Selection bubble on parent focus/hover
|
||||
.md-select:focus-within &,
|
||||
.md-select:hover & {
|
||||
.md-select:is(:focus-within, :hover) & {
|
||||
max-height: px2rem(200px);
|
||||
transform: translate3d(-50%, 0, 0);
|
||||
opacity: 1;
|
||||
@@ -113,8 +112,7 @@
|
||||
}
|
||||
|
||||
// Link on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
color: var(--md-accent-fg-color);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Icon definitions
|
||||
// Repository information variables
|
||||
:root {
|
||||
--md-source-forks-icon: svg-load("octicons/repo-forked-16.svg");
|
||||
--md-source-repositories-icon: svg-load("octicons/repo-16.svg");
|
||||
|
||||
@@ -87,8 +87,7 @@
|
||||
|
||||
// Active link and link on focus/hover
|
||||
&--active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
color: inherit;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -40,38 +40,70 @@
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Rules
|
||||
// Rules: layout
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Tooltip variables
|
||||
:root {
|
||||
--md-tooltip-width: #{px2rem(400px)};
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Tooltip
|
||||
.md-tooltip {
|
||||
position: absolute;
|
||||
// Hack: set an explicit `z-index` so we can transition it to ensure that any
|
||||
// following elements are not overlaying the tooltip during the transition.
|
||||
z-index: 0;
|
||||
top: var(--md-tooltip-y);
|
||||
left:
|
||||
clamp(
|
||||
#{px2rem(16px)},
|
||||
calc(var(--md-tooltip-x) - #{px2rem(16px)}),
|
||||
calc(100vw - var(--md-tooltip-width) - #{px2rem(16px)})
|
||||
);
|
||||
width: var(--md-tooltip-width);
|
||||
max-width: calc(100vw - 2 * #{px2rem(16px)});
|
||||
max-height: 0;
|
||||
overflow: auto;
|
||||
color: var(--md-default-fg-color);
|
||||
background-color: var(--md-default-bg-color);
|
||||
border-radius: px2rem(2px);
|
||||
box-shadow:
|
||||
0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1),
|
||||
0 0 px2rem(1px) hsla(0, 0%, 0%, 0.25);
|
||||
transform: translateY(px2rem(8px));
|
||||
transform: translateY(px2rem(-8px));
|
||||
// Hack: promote to own layer to reduce jitter
|
||||
backface-visibility: hidden;
|
||||
opacity: 0;
|
||||
transition:
|
||||
transform 250ms 375ms,
|
||||
transform 0ms 250ms,
|
||||
opacity 250ms,
|
||||
max-height 0ms 250ms,
|
||||
z-index 250ms;
|
||||
max-height 0ms 250ms;
|
||||
|
||||
// Disable animation for motion reduction preference
|
||||
// [reduced-motion]: Disable animation
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
// Tooltip on parent focus
|
||||
:focus-within > & {
|
||||
max-height: 1000%;
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
transition:
|
||||
transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1),
|
||||
opacity 250ms,
|
||||
max-height 250ms;
|
||||
|
||||
// [reduced-motion]: Disable animation
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Show outline for keyboard devices
|
||||
.focus-visible > & {
|
||||
outline: var(--md-accent-fg-color) auto;
|
||||
}
|
||||
|
||||
// Tooltip wrapper
|
||||
&__inner {
|
||||
padding: px2rem(16px);
|
||||
@@ -87,100 +119,120 @@
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Tooltip on parent focus
|
||||
:focus > &,
|
||||
:focus-within > & {
|
||||
max-height: 1000%;
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
transition:
|
||||
transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1),
|
||||
opacity 250ms,
|
||||
max-height 250ms 0ms,
|
||||
z-index 0ms;
|
||||
|
||||
// Disable animation for motion reduction preference
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Show outline for keyboard devices
|
||||
.focus-visible > & {
|
||||
outline: var(--md-accent-fg-color) auto;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Annotation
|
||||
// Code annotation
|
||||
.md-annotation {
|
||||
white-space: initial;
|
||||
white-space: normal;
|
||||
outline: none;
|
||||
|
||||
// Code annotation is not hidden (e.g. when copying)
|
||||
&:not([hidden]) {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// Promote children to top on focus
|
||||
&:focus-within > * {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
// Annotation is visible
|
||||
&:not([hidden]) {
|
||||
display: inline-block;
|
||||
}
|
||||
// Code annotation wrapper (= tooltip)
|
||||
&__inner {
|
||||
top: calc(var(--md-tooltip-y) + 1.2ch);
|
||||
left:
|
||||
clamp(
|
||||
#{px2rem(0px)},
|
||||
calc(var(--md-tooltip-x) + #{px2rem(12px)}),
|
||||
calc(100vw - var(--md-tooltip-width) - 2 * #{px2rem(16px)})
|
||||
);
|
||||
font-family: var(--md-text-font-family);
|
||||
|
||||
// Annotation index
|
||||
&__index {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
display: inline-block;
|
||||
min-width: 1.4em;
|
||||
padding: 0 px2em(6px);
|
||||
color: hsla(0, 0%, 100%, 1);
|
||||
text-align: center;
|
||||
background-color: var(--md-default-fg-color--lighter);
|
||||
border-radius: px2em(20px);
|
||||
cursor: pointer;
|
||||
transition:
|
||||
color 250ms,
|
||||
background-color 250ms,
|
||||
z-index 250ms;
|
||||
animation: pulse 2000ms infinite;
|
||||
user-select: none;
|
||||
// [mobile -]: Align with body copy
|
||||
@include break-to-device(mobile) {
|
||||
|
||||
// Disable animation for motion reduction preference
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none;
|
||||
animation: none;
|
||||
}
|
||||
|
||||
// Annotation index on focus
|
||||
:focus-within > & {
|
||||
transition:
|
||||
color 250ms,
|
||||
background-color 250ms,
|
||||
z-index 0ms;
|
||||
animation: none;
|
||||
|
||||
// Disable animation for motion reduction preference
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none;
|
||||
// Top-level code block
|
||||
.md-content__inner > :is(pre, .highlight) & {
|
||||
left:
|
||||
clamp(
|
||||
#{px2rem(16px)},
|
||||
calc(var(--md-tooltip-x) + #{px2rem(12px)}),
|
||||
calc(100vw - var(--md-tooltip-width) - #{px2rem(16px)})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Annotation index on focus/hover
|
||||
:focus-within > &,
|
||||
:hover > & {
|
||||
color: var(--md-accent-bg-color);
|
||||
background-color: var(--md-accent-fg-color);
|
||||
// Code annotation tooltip when not focused
|
||||
:not(:focus-within) > & {
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Annotation tooltip
|
||||
.md-tooltip {
|
||||
min-width: px2rem(320px);
|
||||
max-width: 60%;
|
||||
margin: px2em(-16px, 13.6px) px2em(10px, 13.6px) 0;
|
||||
font-family: var(--md-text-font-family);
|
||||
// Code annotation index
|
||||
&__index {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
margin: 0 1ch;
|
||||
color: hsla(0, 0%, 100%, 1);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
// Code annotation index bubble – the bubble must be positioned absolutely
|
||||
// behind the index, because it shouldn't impact the rendering of a code
|
||||
// block. Otherwise, small rounding differences in browsers can sometimes
|
||||
// mess up alignment of text following a code annotation.
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0.1ch;
|
||||
left: -0.2ch;
|
||||
z-index: -1;
|
||||
width: max(2.2ch, 100% + 1.2ch);
|
||||
height: 2.2ch;
|
||||
margin: 0 -0.4ch;
|
||||
padding: 0 0.4ch;
|
||||
background-color: var(--md-default-fg-color--lighter);
|
||||
border-radius: 1em;
|
||||
transition:
|
||||
color 250ms,
|
||||
background-color 250ms;
|
||||
animation: pulse 2000ms infinite;
|
||||
content: "";
|
||||
|
||||
// [reduced-motion]: Disable animation
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none;
|
||||
animation: none;
|
||||
}
|
||||
|
||||
// Code annotation index bubble on focus/hover
|
||||
:is(:focus-within, :hover) > & {
|
||||
background-color: var(--md-accent-fg-color);
|
||||
}
|
||||
|
||||
// Code annotation index bubble on focus
|
||||
:focus-within > & {
|
||||
transition:
|
||||
color 250ms,
|
||||
background-color 250ms;
|
||||
animation: none;
|
||||
|
||||
// [reduced-motion]: Disable animation
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Code annotation index on focus/hover
|
||||
:is(:focus-within, :hover) > & {
|
||||
color: var(--md-accent-bg-color);
|
||||
}
|
||||
|
||||
// Code annotation index on focus
|
||||
:focus-within > & {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,8 +72,7 @@
|
||||
}
|
||||
|
||||
// Back-to-top button on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
color: var(--md-accent-bg-color);
|
||||
background-color: var(--md-accent-fg-color);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Icon definitions
|
||||
// Version selection variables
|
||||
:root {
|
||||
--md-version-icon: svg-load("fontawesome/solid/caret-down.svg");
|
||||
}
|
||||
@@ -110,8 +110,7 @@
|
||||
scroll-snap-type: y mandatory;
|
||||
|
||||
// Version selection list on parent focus/hover
|
||||
.md-version:focus-within &,
|
||||
.md-version:hover & {
|
||||
.md-version:is(:focus-within, :hover) & {
|
||||
max-height: px2rem(200px);
|
||||
opacity: 1;
|
||||
transition:
|
||||
@@ -160,8 +159,7 @@
|
||||
}
|
||||
|
||||
// Link on focus/hover
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:is(:focus, :hover) {
|
||||
color: var(--md-accent-fg-color);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user