CSS + Accessibility: Inclusion Through User Choice

A presentation at CSUN in March 2024 in Anaheim, CA, USA by Carie Fisher

Slide 1

Slide 1

CSS + Accessibility: Inclusion Through User Choice

Slide 2

Slide 2

Slide 3

Slide 3

1 Font family (1440) 69 Web hex colors (1986) 1 JavaScript framework (1995)

Slide 4

Slide 4

650,000 Font families (2024) 16,777,216 Web hex colors (2024) 100+ JavaScript frameworks (2024)

Slide 5

Slide 5

Life is the sum of all your choices — Albert Camus

Slide 6

Slide 6

What do we mean by an accessible choice?

Slide 7

Slide 7

Slide 8

Slide 8

User-focused CSS media features!

Slide 9

Slide 9

Color @prefers-color-scheme @forced-colors @inverted-colors

Slide 10

Slide 10

@prefers-color-scheme (default/light) codepen.io/cariefisher/pen/JjmmRxZ

Slide 11

Slide 11

@prefers-color-scheme (dark) codepen.io/cariefisher/pen/JjmmRxZ

Slide 12

Slide 12

@media (prefers-color-scheme: dark) { body {background-color: #282828;} .without [data-word=”without”] .char:before, .without [data-word=”without”] .char:after { color: #ffffff; } }

Slide 13

Slide 13

caniuse.com/mdn-css_at-rules_media_prefers-color-scheme

Slide 14

Slide 14

@forced-colors (active) codepen.io/cariefisher/pen/JjmmRxZ

Slide 15

Slide 15

@media (forced-colors: active) { body {background-color: #fcba03;} .without [data-word=”without”] .char:before, .without [data-word=”without”] .char:after { color: #ac1663; } .without {color: #004a72;} }

Slide 16

Slide 16

caniuse.com/mdn-css_at-rules_media_forced-colors

Slide 17

Slide 17

@inverted-colors (inverted) Visual of the code before inverted codepen.io/cariefisher/pen/JjmmRxZ

Slide 18

Slide 18

@media (inverted-colors: inverted) { body {background-color: #99cc66;} .without [data-word=”without”] .char:before, .without [data-word=”without”] .char:after { color: #ee1166; } .without {color: #111111;} }

Slide 19

Slide 19

@inverted-colors (inverted) Visual of the code after inverted codepen.io/cariefisher/pen/JjmmRxZ

Slide 20

Slide 20

@media (inverted-colors: inverted) { body { background-color: #663399; filter: invert(100%); } .without [data-word=”without”] .char:before, .without [data-word=”without”] .char:after { color: #11ee99; filter: invert(100%); } .without { color: #eeeeee; filter: invert(100%); } }

Slide 21

Slide 21

@media (inverted-colors: inverted) and (prefers-color-scheme: dark) { body {background: #fcba03;} .without [data-word=”without”] .char:before, .without [data-word=”without”] .char:after { color: #ac1663; } .without {color: #004a72;} }

Slide 22

Slide 22

caniuse.com/mdn-css_at-rules_media_inverted-colors

Slide 23

Slide 23

Contrast @prefers-contrast @prefers-reduced-transparency

Slide 24

Slide 24

@prefers-contrast (no preference) codepen.io/cariefisher/pen/GRYYmoR

Slide 25

Slide 25

@prefers-contrast (more) codepen.io/cariefisher/pen/GRYYmoR

Slide 26

Slide 26

@media (prefers-contrast: more) { .title2 {color: var(—clr-6);} .aurora2__item:nth-of-type(1), .aurora2__item:nth-of-type(2), .aurora2__item:nth-of-type(3), .aurora2__item:nth-of-type(4) { background-color: var(—clr-6); } }

Slide 27

Slide 27

@prefers-contrast (less) codepen.io/cariefisher/pen/GRYYmoR

Slide 28

Slide 28

@media (prefers-contrast: less) { .title {color: var(—clr-5);} .aurora__item:nth-of-type(1), .aurora__item:nth-of-type(2), .aurora__item:nth-of-type(3), .aurora__item:nth-of-type(4) { background-color: var(—clr-5); } }

Slide 29

Slide 29

@prefers-contrast (custom) codepen.io/cariefisher/pen/GRYYmoR

Slide 30

Slide 30

@media (prefers-contrast: custom) { .aurora2__item:nth-of-type(1) { background-color: var(—clr-1); } .aurora2__item:nth-of-type(2) { background-color: var(—clr-2); } .aurora2__item:nth-of-type(3) { background-color: var(—clr-3); } .aurora2__item:nth-of-type(4) { background-color: var(—clr-4); } }

Slide 31

Slide 31

caniuse.com/mdn-css_at-rules_media_prefers-contrast

Slide 32

Slide 32

@prefers-reduced-transparency (reduce) codepen.io/cariefisher/pen/GRYYmoR

Slide 33

Slide 33

@media (prefers-reduced-transparency: reduce) { .title, .title2 { opacity: 0.7; } }

Slide 34

Slide 34

caniuse.com/mdn-css_at-rules_media_prefers-reduced-transparency

Slide 35

Slide 35

Motion @prefers-reduced-motion @prefers-reduced-data

Slide 36

Slide 36

@prefers-reduced-motion (no preference) codepen.io/cariefisher/pen/zYmmZZZ

Slide 37

Slide 37

@prefers-reduced-motion (reduce) codepen.io/cariefisher/pen/zYmmZZZ

Slide 38

Slide 38

@media @media (prefers-reduced-motion: reduce) { .bg-rainbow {animation: none;} .perfection { .word { .char { animation: slide-down 5s cubic-bezier(0.75, 0, 0.25, 1) both; animation-delay: calc(#{$delay} + (0.5s * var(—word-index))); } } [data-word=”perfection”] { animation: slide-over 4.5s cubic-bezier(0.5, 0, 0.25, 1) both; animation-delay: $delay;

Slide 39

Slide 39

.char { animation: none; visibility: hidden; } .char:before, .char:after { animation: split-in 4.5s cubic-bezier(0.75, 0, 0.25, 1) both alternate; animation-delay: calc( 3s + -0.2s * (var(—char-total) - var(—char-index)) ); } } } }

Slide 40

Slide 40

caniuse.com/mdn-css_at-rules_media_prefers-reduced-motion

Slide 41

Slide 41

@prefers-reduced-data (reduce) codepen.io/cariefisher/pen/zYmmZZZ

Slide 42

Slide 42

@media (prefers-reduced-data: reduce) { .bg-rainbow {animation: none;} .perfection { .word { .char { animation: none; } } [data-word=”perfection”] { animation: none;

Slide 43

Slide 43

.char { animation: none; visibility: hidden; } .char:before, .char:after { animation: none; } } } }

Slide 44

Slide 44

caniuse.com/mdn-css_at-rules_media_prefers-reduced-data

Slide 45

Slide 45

Color Contrast Motion @prefers-color-scheme @forced-colors @inverted-colors @prefers-contrast @prefers-reducedtransparency @prefers-reducedmotion @prefers-reduced-data

Slide 46

Slide 46

0 User choices

Slide 47

Slide 47

16 User choices

Slide 48

Slide 48

256 User choices

Slide 49

Slide 49

Our job is to provide options and let people choose their own adventure

Slide 50

Slide 50

Thanks! @cariefisher