diff --git a/README.md b/README.md index 9110aa67b..1c47eec9e 100644 --- a/README.md +++ b/README.md @@ -320,47 +320,47 @@ in the littlefoot instance will stop working, requiring you to call the ## Theming -littlefoot supports theming through [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties). The following properties are available in browsers or [CSS precompilation tools](https://preset-env.cssdb.org/) that support them. +littlefoot supports theming through [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties). The following custom properties are available in browsers or [CSS precompilation tools](https://preset-env.cssdb.org/) that support them, and are scoped to the `.littlefoot` class. ### Buttons -| Button properties | Default value | Purpose | -| :-------------------------------------------- | :---------------------------------------------- | :------------------------------ | -| `--littlefoot-button-background-color` | `#949494` | Button background color. | -| `--littlefoot-button-active-background-color` | `#4c4c4c` | Active button background color. | -| `--littlefoot-button-border-radius` | `0.5rem` | Button border radius. | -| `--littlefoot-button-active-text-color` | `#fafafa` | Active button text color. | -| `--littlefoot-button-height` | `1rem` | Button height. | -| `--littlefoot-button-margin` | `0 0.1rem` | Button margin. | -| `--littlefoot-button-padding` | `0 0.6rem` | Button padding | -| `--littlefoot-button-text-color` | `#fafafa` | Button text color. | -| `--littlefoot-button-transition` | `background-color 0.25s ease, color 0.25s ease` | Button transition animation. | +| Button properties | Default value | Purpose | +| :--------------------------------- | :---------------------------------------------- | :------------------------------ | +| `--button-background-color` | `#949494` | Button background color. | +| `--button-active-background-color` | `#4c4c4c` | Active button background color. | +| `--button-border-radius` | `0.5rem` | Button border radius. | +| `--button-active-text-color` | `#fafafa` | Active button text color. | +| `--button-height` | `1rem` | Button height. | +| `--button-margin` | `0 0.1rem` | Button margin. | +| `--button-padding` | `0 0.6rem` | Button padding | +| `--button-text-color` | `#fafafa` | Button text color. | +| `--button-transition` | `background-color 0.25s ease, color 0.25s ease` | Button transition animation. | ### Popovers -| Popover properties | Default value | Purpose | -| :-------------------------------------------- | :----------------------------------------- | :------------------------------ | -| `--littlefoot-popover-background-color` | `#f5f5f5` | Popover background color. | -| `--littlefoot-popover-border-radius` | `0.5rem` | Popover border radius. | -| `--littlefoot-popover-border` | `1px solid #949494` | Popover border. | -| `--littlefoot-popover-font-family` | `initial` | Popover text font family. | -| `--littlefoot-popover-font-size` | `initial` | Popover text font size. | -| `--littlefoot-popover-font-style` | `initial` | Popover text font style. | -| `--littlefoot-popover-font-weight` | `initial` | Popover text font weight. | -| `--littlefoot-popover-horizontal-padding` | `1.4rem` | Popover horizontal padding. | -| `--littlefoot-popover-line-height` | `normal` | Popover text line height. | -| `--littlefoot-popover-max-height` | `15em` | Maximum popover height. | -| `--littlefoot-popover-max-width` | `90%` | Maximum popover width. | -| `--littlefoot-popover-scroll-indicator-color` | `#4c4c4c` | Popover scroll indicator color. | -| `--littlefoot-popover-shadow` | `0 0 8px rgba(0, 0, 0, 0.3)` | Popover drop shadow. | -| `--littlefoot-popover-text-color` | `#111` | Popover text color. | -| `--littlefoot-popover-tooltip-size` | `0.5rem` | Popover tooltip size. | -| `--littlefoot-popover-transform-origin` | `50% 0` | Popover transform origin. | -| `--littlefoot-popover-transform` | `scale(0.1) translateZ(0)` | Initial popover transform. | -| `--littlefoot-popover-active-transform` | `scale(1) translateZ(0)` | Activated popover transform. | -| `--littlefoot-popover-transition` | `opacity 0.25s ease, transform 0.25s ease` | Popover transition animation. | -| `--littlefoot-popover-vertical-padding` | `0.6rem` | Popover vertical padding. | -| `--littlefoot-popover-width` | `22em` | Popover width. | +| Popover properties | Default value | Purpose | +| :--------------------------------- | :----------------------------------------- | :------------------------------ | +| `--popover-background-color` | `#f5f5f5` | Popover background color. | +| `--popover-border-radius` | `0.5rem` | Popover border radius. | +| `--popover-border` | `1px solid #949494` | Popover border. | +| `--popover-font-family` | `initial` | Popover text font family. | +| `--popover-font-size` | `initial` | Popover text font size. | +| `--popover-font-style` | `initial` | Popover text font style. | +| `--popover-font-weight` | `initial` | Popover text font weight. | +| `--popover-horizontal-padding` | `1.4rem` | Popover horizontal padding. | +| `--popover-line-height` | `normal` | Popover text line height. | +| `--popover-max-height` | `15em` | Maximum popover height. | +| `--popover-max-width` | `90%` | Maximum popover width. | +| `--popover-scroll-indicator-color` | `#4c4c4c` | Popover scroll indicator color. | +| `--popover-shadow` | `0 0 8px rgba(0, 0, 0, 0.3)` | Popover drop shadow. | +| `--popover-text-color` | `#111` | Popover text color. | +| `--popover-tooltip-size` | `0.5rem` | Popover tooltip size. | +| `--popover-transform-origin` | `50% 0` | Popover transform origin. | +| `--popover-transform` | `scale(0.1) translateZ(0)` | Initial popover transform. | +| `--popover-active-transform` | `scale(1) translateZ(0)` | Activated popover transform. | +| `--popover-transition` | `opacity 0.25s ease, transform 0.25s ease` | Popover transition animation. | +| `--popover-vertical-padding` | `0.6rem` | Popover vertical padding. | +| `--popover-width` | `22em` | Popover width. | ### Backwards compatibility diff --git a/src/dom/document.ts b/src/dom/document.ts index 5d0b79bf1..e343a1776 100644 --- a/src/dom/document.ts +++ b/src/dom/document.ts @@ -37,7 +37,7 @@ type OriginalData = Readonly<{ }> const CLASS_PRINT_ONLY = 'littlefoot--print' -const CLASS_HOST = 'littlefoot__host' +const CLASS_HOST = 'littlefoot' const setPrintOnly = (el: Element) => addClass(el, CLASS_PRINT_ONLY) diff --git a/src/littlefoot.css b/src/littlefoot.css index d5f51970d..b67513144 100644 --- a/src/littlefoot.css +++ b/src/littlefoot.css @@ -1,59 +1,57 @@ -@custom-media --littlefoot-breakpoint (width < 768px); - -:root { - --littlefoot-button-background-color: #949494; - --littlefoot-button-text-color: #fafafa; - --littlefoot-button-active-background-color: #4c4c4c; - --littlefoot-button-active-text-color: #fafafa; - --littlefoot-button-border-radius: 0.5rem; - --littlefoot-button-height: 1rem; - --littlefoot-button-margin: 0 0.1rem; - --littlefoot-button-padding: 0 0.6rem; - --littlefoot-button-transition: background-color 0.25s ease, color 0.25s ease; - --littlefoot-popover-background-color: #f5f5f5; - --littlefoot-popover-text-color: #111; - --littlefoot-popover-border: 1px solid #949494; - --littlefoot-popover-border-radius: 0.5rem; - --littlefoot-popover-max-height: 15em; - --littlefoot-popover-max-width: 90%; - --littlefoot-popover-horizontal-padding: 1.4rem; - --littlefoot-popover-vertical-padding: 0.6rem; - --littlefoot-popover-shadow: 0 0 8px rgba(0, 0, 0, 0.3); - --littlefoot-popover-transform-origin: 50% 0; - --littlefoot-popover-transform: scale(0.1) translateZ(0); - --littlefoot-popover-active-transform: scale(1) translateZ(0); - --littlefoot-popover-transition: opacity 0.25s ease, transform 0.25s ease; - --littlefoot-popover-width: 22em; - --littlefoot-popover-scroll-indicator-color: #4c4c4c; - --littlefoot-popover-tooltip-size: 0.5rem; -} +@custom-media --breakpoint (width < 768px); + +.littlefoot { + --button-background-color: #949494; + --button-text-color: #fafafa; + --button-active-background-color: #4c4c4c; + --button-active-text-color: #fafafa; + --button-border-radius: 0.5rem; + --button-height: 1rem; + --button-margin: 0 0.1rem; + --button-padding: 0 0.6rem; + --button-transition: background-color 0.25s ease, color 0.25s ease; + --popover-background-color: #f5f5f5; + --popover-text-color: #111; + --popover-border: 1px solid #949494; + --popover-border-radius: 0.5rem; + --popover-max-height: 15em; + --popover-max-width: 90%; + --popover-horizontal-padding: 1.4rem; + --popover-vertical-padding: 0.6rem; + --popover-shadow: 0 0 8px rgba(0, 0, 0, 0.3); + --popover-transform-origin: 50% 0; + --popover-transform: scale(0.1) translateZ(0); + --popover-active-transform: scale(1) translateZ(0); + --popover-transition: opacity 0.25s ease, transform 0.25s ease; + --popover-width: 22em; + --popover-scroll-indicator-color: #4c4c4c; + --popover-tooltip-size: 0.5rem; -.littlefoot__host { position: relative; } .littlefoot__button { - background-color: var(--littlefoot-button-background-color); - border-radius: var(--littlefoot-button-border-radius); - border: var(--littlefoot-button-border, 0); - color: var(--littlefoot-button-text-color); + background-color: var(--button-background-color); + border-radius: var(--button-border-radius); + border: var(--button-border, 0); + color: var(--button-text-color); cursor: pointer; display: inline-block; - font-size: var(--littlefoot-button-font-size, 0.75rem); - font-weight: var(--littlefoot-button-font-weight, initial); - height: var(--littlefoot-button-height); - margin: var(--littlefoot-button-margin); - padding: var(--littlefoot-button-padding); + font-size: var(--button-font-size, 0.75rem); + font-weight: var(--button-font-weight, initial); + height: var(--button-height); + margin: var(--button-margin); + padding: var(--button-padding); text-decoration: none; - transition: var(--littlefoot-button-transition); + transition: var(--button-transition); vertical-align: middle; &:hover, &:focus, &:active, &.is-active { - background-color: var(--littlefoot-button-active-background-color); - color: var(--littlefoot-button-active-text-color); + background-color: var(--button-active-background-color); + color: var(--button-active-text-color); } & svg { @@ -63,23 +61,17 @@ } .littlefoot__popover { - border: var(--littlefoot-popover-border); - border-radius: var(--littlefoot-popover-border-radius); - box-shadow: var(--littlefoot-popover-shadow); - left: 0; - margin: calc( - (1.4 * var(--littlefoot-popover-tooltip-size)) + - var(--littlefoot-button-height) - ) - 0; - max-width: var(--littlefoot-popover-max-width); + border: var(--popover-border); + border-radius: var(--popover-border-radius); + box-shadow: var(--popover-shadow); + margin: calc(2.5 * var(--popover-tooltip-size)) 0; + max-width: var(--popover-max-width); position: absolute; top: 0; - transform-origin: var(--littlefoot-popover-transform-origin); - transform: var(--littlefoot-popover-transform); - transition: var(--littlefoot-popover-transition); - width: var(--littlefoot-popover-width); - z-index: 1; + transform-origin: var(--popover-transform-origin); + transform: var(--popover-transform); + transition: var(--popover-transition); + width: var(--popover-width); &.is-above { bottom: 0; @@ -87,60 +79,29 @@ } &.is-active { - transform: var(--littlefoot-popover-active-transform); - } -} - -@media (--littlefoot-breakpoint) { - .littlefoot__popover { - border-radius: 0; - border-width: 1px 0 0; - bottom: 0; - left: 0 !important; - margin: 0; - max-width: 100% !important; - position: fixed; - right: 0; - top: auto; - transform: translateY(100%); - width: 100%; - - &.is-active { - transform: translateY(0); - } - } - - .littlefoot__wrapper { - border-radius: 0; - max-width: 100% !important; - transform: none; - } - - .littlefoot__tooltip { - display: none; + transform: var(--popover-active-transform); } } .littlefoot__wrapper { - border-radius: var(--littlefoot-popover-border-radius); + border-radius: var(--popover-border-radius); position: relative; - z-index: 3; + z-index: 1; } .littlefoot__content { -webkit-overflow-scrolling: touch; - background-color: var(--littlefoot-popover-background-color); - border-radius: var(--littlefoot-popover-border-radius); - color: var(--littlefoot-popover-text-color); - font-family: var(--littlefoot-popover-font-family, initial); - font-size: var(--littlefoot-popover-font-size, initial); - font-style: var(--littlefoot-popover-font-style, initial); - font-weight: var(--littlefoot-popover-font-weight, initial); - line-height: var(--littlefoot-popover-line-height, normal); - max-height: var(--littlefoot-popover-max-height); + background-color: var(--popover-background-color); + border-radius: var(--popover-border-radius); + color: var(--popover-text-color); + font-family: var(--popover-font-family, initial); + font-size: var(--popover-font-size, initial); + font-style: var(--popover-font-style, initial); + font-weight: var(--popover-font-weight, initial); + line-height: var(--popover-line-height, normal); + max-height: var(--popover-max-height); overflow: auto; - padding: var(--littlefoot-popover-vertical-padding) - var(--littlefoot-popover-horizontal-padding); + padding: var(--popover-vertical-padding) var(--popover-horizontal-padding); position: relative; & img { @@ -154,17 +115,16 @@ .is-scrollable { & .littlefoot__content::after { - bottom: calc(var(--littlefoot-popover-vertical-padding) / 2); - color: var(--littlefoot-popover-scroll-indicator-color); + bottom: calc(var(--popover-vertical-padding) / 2); + color: var(--popover-scroll-indicator-color); content: '\21E3'; display: block; left: 0; opacity: 1; position: fixed; text-align: center; - transition: var(--littlefoot-popover-transition); - width: var(--littlefoot-popover-horizontal-padding); - z-index: 3; + transition: var(--popover-transition); + width: var(--popover-horizontal-padding); } &.is-fully-scrolled .littlefoot__content::after { @@ -173,27 +133,54 @@ } .littlefoot__tooltip { - --littlefoot-s: -1; - - background-color: var(--littlefoot-popover-background-color); - border: var(--littlefoot-popover-border); - box-shadow: var(--littlefoot-popover-shadow); - height: calc(2 * var(--littlefoot-popover-tooltip-size)); - margin-left: calc( - var(--littlefoot-s) * var(--littlefoot-popover-tooltip-size) - ); + --minus-one: -1; + + background-color: var(--popover-background-color); + border: var(--popover-border); + box-shadow: var(--popover-shadow); + height: calc(2 * var(--popover-tooltip-size)); + margin-left: calc(var(--minus-one) * var(--popover-tooltip-size)); position: absolute; transform: rotate(45deg); - width: calc(2 * var(--littlefoot-popover-tooltip-size)); - z-index: 2; + width: calc(2 * var(--popover-tooltip-size)); } .is-below .littlefoot__tooltip { - top: calc(var(--littlefoot-s) * var(--littlefoot-popover-tooltip-size)); + top: calc(var(--minus-one) * var(--popover-tooltip-size)); } .is-above .littlefoot__tooltip { - bottom: calc(var(--littlefoot-s) * var(--littlefoot-popover-tooltip-size)); + bottom: calc(var(--minus-one) * var(--popover-tooltip-size)); +} + +@media (--breakpoint) { + .littlefoot__popover { + border-radius: 0; + border-width: 1px 0 0; + bottom: 0; + left: 0 !important; + margin: 0; + max-width: 100% !important; + position: fixed; + right: 0; + top: auto; + transform: translateY(100%); + width: 100%; + + &.is-active { + transform: translateY(0); + } + } + + .littlefoot__wrapper { + border-radius: 0; + max-width: 100% !important; + transform: none; + } + + .littlefoot__tooltip { + display: none; + } } @media not print { diff --git a/test/setup.test.ts b/test/setup.test.ts index 9ef8fc7c5..74d218d9e 100644 --- a/test/setup.test.ts +++ b/test/setup.test.ts @@ -14,7 +14,7 @@ beforeEach(() => { test('creates one button and one host per footnote call', () => { littlefoot() - expect(document.querySelectorAll('.littlefoot__host')).toHaveLength(4) + expect(document.querySelectorAll('.littlefoot')).toHaveLength(4) expect(getAllButtons()).toHaveLength(4) }) @@ -46,7 +46,7 @@ test('sets ARIA attributes on button', () => { test('sets up footnotes with a URL before the fragment', () => { setDocumentBody('filename.html') littlefoot() - expect(document.querySelectorAll('.littlefoot__host')).toHaveLength(1) + expect(document.querySelectorAll('.littlefoot')).toHaveLength(1) expect(getAllButtons()).toHaveLength(1) }) diff --git a/test/unmount.test.ts b/test/unmount.test.ts index 94a041049..1ba52a2f7 100644 --- a/test/unmount.test.ts +++ b/test/unmount.test.ts @@ -9,7 +9,7 @@ beforeEach(() => { test('unmount removes all buttons', () => { const instance = littlefoot() instance.unmount() - expect(document.querySelectorAll('.littlefoot__host')).toHaveLength(0) + expect(document.querySelectorAll('.littlefoot')).toHaveLength(0) expect( screen.queryAllByRole('button', { name: /See Footnote/ }) ).toHaveLength(0)