diff --git a/docs/index.html b/docs/index.html index 801cf99..16f04a1 100644 --- a/docs/index.html +++ b/docs/index.html @@ -18,6 +18,7 @@

Presentations

Resources

The GitHub repository contains the image assets.

diff --git a/docs/slides-cssingraz2024/README.md b/docs/slides-cssingraz2024/README.md new file mode 100644 index 0000000..110a7b0 --- /dev/null +++ b/docs/slides-cssingraz2024/README.md @@ -0,0 +1,18 @@ +# Slides for “High Contrast Mode, for real” talk + +## Abstract + +High Contrast Mode (or better Forced Colors Mode) support is better than ever. Let’s learn what can be done to make websites more accessible for people that have `forced-colors` turned on. + +## Talk given at + +CSS in Graz [Meetup #3](https://www.meetup.com/css-in-graz/events/298298652/) 2024 +#css-in-graz +https://www.meetup.com/css-in-graz/ + + +## Author/Speaker + +Matthias Zöchling +@CSSence +https://cssence.com/ diff --git a/docs/slides-cssingraz2024/download.pdf b/docs/slides-cssingraz2024/download.pdf new file mode 100644 index 0000000..11ce64b Binary files /dev/null and b/docs/slides-cssingraz2024/download.pdf differ diff --git a/docs/slides-cssingraz2024/index.html b/docs/slides-cssingraz2024/index.html new file mode 100644 index 0000000..1bc9c58 --- /dev/null +++ b/docs/slides-cssingraz2024/index.html @@ -0,0 +1,293 @@ + + + + +High Contrast Mode, for real | @CSSence | #CSS-in-Graz + + + + + + + + +
+
+

High Contrast Mode, for real

+

@CSSence
🗣 Matthias Zöchling

+

CSS in Graz
🌐 Graz, Austria

+
+
+ +
+
+

What?

+

(High) Contrast Mode?

+
+
+ +
+
+
+

The main feature is that it limits and controls the range of colors, making it easier for users to emphasize content and UI in a way that works for them.

+

In other words, they force colors.

+ +
+
+
+ +
+
+
+

Unlike other operating system display modes that invert colors or set a dark mode flag, Windows High Contrast Mode completely overrides authored colors with user-set colors.

+ +
+
+
+ +
+

The Settings Page in Windows 10, navigated to Ease of Access, Vision, High Contrast.

+

The same Settings page, but now High Contrast Mode is turned on: A theme with light text on dark background chosen.

+

+
+ +
+
+

⚠️ Low Contrast

+
+

High Contrast Mode is used by some to produce low contrast on the screen.

+ +
+
+
+ +
+
+

Why?

+
+

[Microsoft] has said that upwards of 4% of their users do [force colors].

+ +
+
+
+ +
+
+

How?

+ +

*) …, use native HTML instead.

+
+
+ +
+
+

OS

+ +
+
+ +
+
+

Browsers

+

Support is good.*

+

*) With Safari being the exception.

+
+
+ +
+
+
+

There is a ton of prior content discussing Windows High Contrast Mode (WHCM) and web content. The catch is that content covers four (five?) different implementations across more than a decade of support: Internet Explorer, Edge, the other Edge, Edge plus IE aliasing, and hardly anything on Firefox. Which means much of it no longer applies.

+ +
+
+
+ +
+
+

For real!

+

🥁

+
+
+ +
+
+

What happens… (1/2)

+ +
+
+ +
+
+

What happens… (2/2)

+ +
+
+ +
+
+

The media query

+
@media (forced-colors: active*) {
+	…
+}
+

*) none | active

+
+
+ +
+
+

The other media query

+
@media (prefers-contrast: more*) {
+	…
+}
+

*) no-preference | more | less | custom

+
+
+ +
+
+

The future media query?

+
@media (prefers-contrast: forcedcustom) {
+	…
+}
+

blogs.windows.com/msedgedev/2020/09/17/styling[…]-forced-colors

+
+
+ +
+
+

The retired media query

+
@media (-ms-high-contrast: active) {
+	…
+}
+
+
+ +
+
+

Combining media queries

+
@media (forced-colors: active) and
+       (prefers-color-scheme: dark) {
+	…
+}
+
+
+ +
+
+

The ToDo List (1/2)

+ +
+
+ +
+
+

Transparent is a color

+
:focus {
+	outline: none;
+	outline: 0.125rem solid transparent;
+	box-shadow: 0 0 0.25rem #bada55;
+}
+
+
+ +
+
+

The ToDo List (2/2)

+ +
+
+ +
+
+

The Backplate

+

The same picture of a cat two times, left and right. The text ‘Hello Kitty!’ has been placed on top of each. However, the right one also shows a black background behind the text, hiding parts of the cat for better legibility. This background is called a backplate in High Contrast Mode.
Image on the right has backplate applied.

+
+
+ +
+
+

The Override

+
.element {
+	forced-color-adjust: none*;
+}
+

*) auto | none | preserve-parent-color

+
+
+ +
+
+

⚠️ Testing

+

Always test multiple themes, especially …

+ +
+
+ +
+
+

⚠️ color(s)

+
@media (forced-colors: active) {
+	…
+}
+.element {
+	forced-color-adjust: none;
+}
+
+
+ +
+
+
+

You’ve made it this far!

+

🙌

+
+
+ + + + + diff --git a/docs/slides-cssingraz2024/slide.js b/docs/slides-cssingraz2024/slide.js new file mode 100644 index 0000000..433ed26 --- /dev/null +++ b/docs/slides-cssingraz2024/slide.js @@ -0,0 +1,43 @@ +const init = () => { + const slides = document.querySelectorAll('body > div'); + const slideMap = []; + slides.forEach((slide, index) => { + slideMap[index] = slide.querySelectorAll('[data-step]').length; + }); + let current = 0; + const slide = (dir) => { + if (slideMap[current]) { + const currentStep = parseInt(slides[current].getAttribute('data-current'), 10); + if (currentStep + dir >= 0 && currentStep + dir <= slideMap[current]) { + slides[current].setAttribute('data-current', '' + (currentStep + dir)); + return; + } + } + if (current + dir < 0 || current + dir >= slides.length) return; + slides[current].removeAttribute('data-current'); + current += dir; + slides[current].setAttribute('data-current', dir === -1 ? '' + slideMap[current] : '0'); + }; + const navigate = (event) => { + const dir = {'ArrowUp': -1, 'ArrowLeft': -1, 'ArrowRight': 1, 'ArrowDown': 1}[event.key]; + if (dir) slide(dir); + }; + const act = (event) => { + const target = '#interactive'; + if (location.hash === target) { + slides[current].setAttribute('data-current', '0'); + window.addEventListener('keydown', navigate); + } else if (event && new URL(event.oldURL).hash === target) { + slides[current].removeAttribute('data-current'); + current = 0; + window.removeEventListener('keydown', navigate); + } + }; + act(); + window.addEventListener("hashchange", act); +}; +if (document.readyState !== 'loading') { + init(); +} else { + document.addEventListener('DOMContentLoaded', init); +} diff --git a/docs/slides-cssingraz2024/style.css b/docs/slides-cssingraz2024/style.css new file mode 100644 index 0000000..831b9a4 --- /dev/null +++ b/docs/slides-cssingraz2024/style.css @@ -0,0 +1,306 @@ +*, +*::before, +*::after { + box-sizing: border-box; +} +:root { + color-scheme: dark light; +} +:focus { + outline: .125rem solid #d34b6c; +} +html { + font: 100%/1.5 sans-serif; +} +html:not(:target) body { + max-inline-size: 70ch; + margin-inline: auto; +} +body { + margin: 0; + padding-block: 3.625em; + padding-inline: 16px; + scroll-behavior: auto; +} +@media (prefers-reduce-motion: no-preference) { + body { + scroll-behavior: smooth; + } +} +h1, +h2, +h3 { + line-height: 1.25; +} +img { + max-inline-size: 100%; +} +em, +i, +cite { + font-style: inherit; +} +blockquote { + margin-inline: 24px; + padding-inline: .875em; + border-inline-start: .125rem solid; +} +small, +blockquote footer { + display: block; + font-size: 87.5%; +} +i { + display: inline-block; + inline-size: 1.333em; + text-align: center; + filter: grayscale(); +} + +#interactive:target :not(a) { + cursor: default; +} +#interactive:target { + background-color: #000; + color: #fff; +} +#interactive:target body { + margin: 0; +} +#interactive:target, +#interactive:target body { + block-size: 100dvh; + inline-size: 100vw; + overflow: hidden; +} +#interactive:target small, +#interactive:target blockquote footer { + font-size: 66.667%; +} +#interactive:target nav { + display: none; +} +#interactive:target a { + color: #d34b6c; +} +#interactive:target mark { + display: inline-block; + background-color: #d34b6c; + color: #fff; + outline: .125rem solid #d34b6c; +} +#interactive:target body > div { + position: absolute; + inset-block-start: -100dvh; + inset-inline-start: 0; + block-size: 100dvh; + inline-size: 100vw; + overflow: hidden; + transition: inset .5s ease-in; +} +#interactive:target body > div:first-of-type { + inset-block-start: 0; + inset-inline-start: 100vw; +} +#interactive:target body > div:has(h1) { + background: + linear-gradient(to right, #000 calc(100vw - 70dvh), #0000 100vw) right no-repeat, + url(uhrturm.webp) right/auto 100dvh no-repeat + #000; +} +#interactive:target body > div:has(h1) div { + inline-size: auto; +} + +#interactive:target div div { + margin-inline: 0; + padding-block-start: 20dvh; + padding-inline: 16px; +} +#interactive:target div div, +#interactive:target blockquote { + inline-size: max-content; + max-inline-size: var(--size, 60vw); + margin-inline: auto; +} +#interactive:target :is(h1, h2, h3) { + font-size: 150%; +} +#interactive:target :is(h1, h2, h3, ul, li, p, pre) { + margin-block: 0 .75em; +} +#interactive:target pre { + padding-block: .5rem; + padding-inline: 1.5rem; + background-color: #8884; + tab-size: 4; +} +#interactive:target :not(pre) > code { + background-color: #8884; + outline: .125rem solid #8884; +} +#interactive:target :is(h2, h3) { + text-align: center; +} +#interactive:target div > ul { + padding-inline-start: 0; +} +#interactive:target ul ul li { + margin-block-end: 0; +} +#interactive:target p { + text-align: var(--align, start); +} +#interactive:target body > div > p { + margin: 0; +} +#interactive:target p > img:only-child { + position: absolute; + block-size: var(--size, 100dvh); + margin-inline: auto; + inset-block-start: var(--y, 0); + inset-inline-start: var(--x, 50vw); + transform: translateX(-50%); +} +#interactive:target img:not(:only-child) { + max-inline-size: none; +} +#interactive:target p > i:only-child { + font-size: 300%; +} + +#interactive:target body > div[data-current] { + inset-block-start: 0; + inset-inline-start: 0; +} +#interactive:target body > div[data-current] ~ div { + inset-block-start: 100dvh; +} +#interactive:target b { + position: absolute; + font-size: 66.667%; +} +#interactive:target [data-step] { + opacity: 0; + transition: opacity .3s ease-in; +} +#interactive:target [data-current="1"] :where([data-step="1"]), +#interactive:target [data-current="2"] :where([data-step="1"], [data-step="2"]), +#interactive:target [data-current="3"] :where([data-step="1"], [data-step="2"], [data-step="3"]), +#interactive:target body > div:has(~ [data-current]) [data-step], +#interactive:target [data-step]:has(~ [data-step="active"]) { + opacity: 1; +} +@media (orientation: landscape) { + #interactive:target { + font-size: 4.5dvh; + } +} +@media (orientation: portrait) { + #interactive:target div div, + #interactive:target blockquote { + max-inline-size: 100%; + } + #interactive:target img { + max-block-size: 100%; + } + nav { + position: fixed !important; + } +} + +@media print { + html { + font-size: 18pt; + } + body { + margin: 0; + padding: 0; + } + html, + body { + height: 100%; + } + body > div { + block-size: 100%; + } + body > div { + position: relative; + block-size: 100%; + padding-block-start: 40mm; + padding-inline: 30mm; + } + body > div ~ div { + page-break-before: always; + } + body > div:has(img:only-child) { + display: flex; + gap: 0 5mm; + padding-block-start: 0; + padding-inline: 0; + } + a { + color: inherit !important; + text-decoration: none; + } + a::before { + content: '🔗' ' ' attr(href); + display: block; + position: absolute; + inset-block-end: 0; + inset-inline-start: 0; + font-size: 75%; + } + a::after { + content: ' ' '🔗'; + font-size: 75%; + } + nav { + display: none; + } +} + +nav { + display: flex; + gap: 1em; + justify-content: center; + position: absolute; + z-index: 1; + block-size: var(--nav-size); + inset-block-start: 0; + inset-inline: 0; + padding-block: calc(.5em + 1px) .5em; + padding-inline: inherit; + background-color: Canvas; + border-block-end: 1px solid transparent; + box-shadow: 0 1px 4px #80808040; +} +@media (prefers-color-scheme: dark) { + nav { + background-image: linear-gradient(#fff2, #fff2); + box-shadow: none; + } +} +nav a { + display: inline-block; + padding-block: .375em; + padding-inline: .5em; + background-color: CanvasText; + color: Canvas; + border: 2px solid transparent; + border-radius: .25em; + text-decoration: none; + forced-color-adjust: none; +} +[data-alternate]::after { + content: attr(data-alternate); + position: relative; + top: -1px; + margin-inline-start: 1ex; + padding: 0 .25em; + background: Canvas; + border: 1px solid Canvas; + border-radius: .25em; + color: CanvasText; + font-size: 75%; +} diff --git a/docs/slides-cssingraz2024/uhrturm.webp b/docs/slides-cssingraz2024/uhrturm.webp new file mode 100644 index 0000000..18324e4 Binary files /dev/null and b/docs/slides-cssingraz2024/uhrturm.webp differ diff --git a/docs/slides-cssingraz2024/win-hcm-backplate.webp b/docs/slides-cssingraz2024/win-hcm-backplate.webp new file mode 100644 index 0000000..b216ce6 Binary files /dev/null and b/docs/slides-cssingraz2024/win-hcm-backplate.webp differ diff --git a/docs/slides-cssingraz2024/win10-hcm-off.webp b/docs/slides-cssingraz2024/win10-hcm-off.webp new file mode 100644 index 0000000..95a1fec Binary files /dev/null and b/docs/slides-cssingraz2024/win10-hcm-off.webp differ diff --git a/docs/slides-cssingraz2024/win10-hcm-on.webp b/docs/slides-cssingraz2024/win10-hcm-on.webp new file mode 100644 index 0000000..5006915 Binary files /dev/null and b/docs/slides-cssingraz2024/win10-hcm-on.webp differ diff --git a/docs/slides-cssingraz2024/win10-hcm-themes.webp b/docs/slides-cssingraz2024/win10-hcm-themes.webp new file mode 100644 index 0000000..8c41d46 Binary files /dev/null and b/docs/slides-cssingraz2024/win10-hcm-themes.webp differ diff --git a/docs/slides-dotcss2016/README.md b/docs/slides-dotcss2016/README.md index d5b3e64..a01f50c 100644 --- a/docs/slides-dotcss2016/README.md +++ b/docs/slides-dotcss2016/README.md @@ -8,11 +8,11 @@ Websites have become boring. The fun project http://adventurega.me/bootstrap/ by dotCSS 2016 @dotCSS -[https://2016.dotcss.io/](http://2016.dotcss.io/) +https://2016.dotcss.io/ ## Author/Speaker Matthias Beitl -@cssence -[https://cssence.com/](http://cssence.com/) +@CSSence +https://cssence.com/ diff --git a/docs/slides-dotcss2016/index.html b/docs/slides-dotcss2016/index.html index adb0db4..0b076f6 100644 --- a/docs/slides-dotcss2016/index.html +++ b/docs/slides-dotcss2016/index.html @@ -3,9 +3,10 @@ - Diversity in Style | @cssence | dotCSS - + Diversity in Style | @CSSence | dotCSS + +