High Contrast, A PostCSS Plugin Story*

Avatar of Eduard Pochtar
Eduard Pochtar am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

*Basiert auf wahren Begebenheiten

Es ist heute schwer, sich ein Leben ohne Internet vorzustellen. Viele Menschen sind mehr oder weniger an das Internet gebunden. Denken Sie an alles, wofür wir es brauchen: Kommunikation, Bildung, Einkaufen, Geschäftskontrolle, Wohnungsverwaltung, Unterhaltung usw. Es ist wie eine Welt in einer anderen Welt, mit eigenen Regeln und Vielfalt.

Rund 80 Millionen Menschen in der EU sind behindert und diese Zahl wächst. Die traurige Wahrheit ist, dass viele von ihnen nicht alle Möglichkeiten des Internets nutzen können, weil so viele von ihnen sich nicht um Barrierefreiheit kümmern.

Was können wir dagegen tun?

Das ist eine gute Frage. Wir leben in einer Zeit, in der Technologien uns helfen können, uns um Menschen zu kümmern, die besondere Fürsorge benötigen. Immer mehr Organisationen, Unternehmen und sogar Regierungen engagieren sich, um Menschen mit Behinderungen zu helfen.

Gesetz zur Barrierefreiheit im Web

Nicht allzu lange ist es her, da verabschiedete die EU ein Gesetz zur Barrierefreiheit im Web. Dieses Gesetz gilt für Websites und mobile Apps des öffentlichen Sektors, wie Verwaltungen, Polizeibehörden, öffentliche Krankenhäuser, Universitäten und Bibliotheken. Es verpflichtet sie, für alle Bürger zugänglich zu sein – insbesondere für Blinde, Hörgeschädigte, Gehörlose sowie Menschen mit Sehschwäche und funktionellen Beeinträchtigungen.

Neue Regeln, die in der EU-Richtlinie zur Barrierefreiheit im Web akzeptiert wurden, sind:

  • Alle von EU-Mitgliedsregierungen besessenen Websites oder Webanwendungen müssen für Menschen mit Behinderungen vollständig zugänglich sein. Neue Websites müssen zugänglich sein und bestehende Inhalte müssen aktualisiert werden.
  • Archivierte Inhalte und Dokumente werden auf Anfrage in zugänglicher Form erhältlich sein.
  • Videos von Regierungen müssen mit Untertiteln versehen werden. Live-Videos haben ein Zeitfenster von 14 Tagen ab der ersten Ausstrahlung, um Untertitel zu erhalten.
  • Online-Dienste, wie z.B. die Bezahlung von Bußgeldern oder Gebühren, müssen zugänglich sein.
  • EU-Regierungs-Websites müssen angeben, ob (und warum) Teile ihrer Website unzugänglich sind.
  • EU-Mitgliedstaaten müssen den zugänglichen Status ihrer Webdienste regelmäßig überwachen und sowohl der Öffentlichkeit als auch der Europäischen Kommission berichten.

In einer Pressemitteilung erklärte Günther H. Oettinger, Kommissar für die Digitale Wirtschaft und Gesellschaft:

Es ist nicht akzeptabel, dass Millionen europäischer Bürger in der digitalen Gesellschaft zurückgelassen werden. Die gerade erzielte Einigung wird sicherstellen, dass jeder die gleichen Chancen hat, die Vorteile des Internets und mobiler Apps zu nutzen, sich stärker in die Gesellschaft einzubringen und ein unabhängigeres Leben zu führen.

Diese Meinung teilte auch Andrus Ansip, Vizepräsident für den digitalen Binnenmarkt:

Internetzugang sollte für alle eine Realität sein. Millionen von Europäern zurückzulassen ist keine Option. Die heutige Einigung ist ein wichtiger Schritt in Richtung eines digitalen Binnenmarktes, der darauf abzielt, Barrieren abzubauen, damit alle Europäer das Beste aus der digitalen Welt herausholen können.

Ich halte es für sehr wichtig zu verstehen, dass das Internet der Ort ist, an dem jeder gleich ist. Und ich denke, dass das Internet heutzutage de facto in der einen oder anderen Form für so viele Benutzer wie möglich zugänglich sein sollte.

Ich möchte unsere Geschichte erzählen, wie wir ein Werkzeug entwickelt haben, das hilft, eine High-Contrast-Version einer Website zu entwickeln.

Kontrast ist wichtig

Kontrast erleichtert die Unterscheidung zwischen einer Sache und einer anderen. Im Webdesign bezieht sich Kontrast normalerweise auf den Unterschied zwischen Vorder- und Hintergrund von Text. Mit anderen Worten, wie unterschiedlich sind die Wörter auf dem Bildschirm vom Hintergrund, auf dem sie liegen.

Textkontrast ist ein wichtiges Kriterium für Barrierefreiheit. Wenn Menschen Websites oder Apps nutzen, lesen sie nicht, sie scannen. Wenn die meisten Menschen schnell scannen oder lesen, verlassen sie sich auf Wort- und Zeichenformen und nicht auf expliziter bewusste Strategien wie das Analysieren jedes Buchstabens und seiner Reihenfolge. Sie tun das wahrscheinlich gerade jetzt, indem Sie gut kontrastierenden Text verwenden, der diese Formen leicht erkennbar macht.

Hoher Kontrast

In einigen Ländern verlangen Regierungen von öffentlichen Websites spezielle High-Contrast-Versionen mit invertierten Farben. Sie kennen sie vielleicht an diesem Symbol

Diese High-Contrast-Einstellung kommt Nutzern mit Sehschwäche oder anderen visuellen Beeinträchtigungen zugute.

Die Herausforderung

Vor nicht allzu langer Zeit stand unser Team vor einem Projekt, das eine High-Contrast-Version erforderte. Und es war eine große Herausforderung für uns alle.

Zuerst durchforsteten wir das Internet auf der Suche nach Informationen darüber, was High Contrast ist und wie es funktionieren sollte. Leider fanden wir nicht genug Informationen. Alles war sehr abstrakt und mangelhaft. Aber einige Informationen fanden wir nützlich. Der Hintergrund sollte dunkel (schwarz) sein, Text – die entgegengesetzte Farbe des Hintergrunds (weiß), Links – gelb oder grün.

Manche Websites invertieren sogar Bilder, manche entfernen Bilder komplett aus der High-Contrast-Version.

CSS-Präprozessoren

Eine Möglichkeit, eine High-Contrast-Version einer Website zu erstellen, ist die Verwendung von Präprozessoren wie Less, Sass oder Stylus. Präprozessoren bieten uns auch viele Möglichkeiten, zwei Versionen einer Website zu kompilieren. Zum Beispiel Variablen

$high-contrast: true;
$background-color: #fff;
$background-high-contrast-color: #000;
$text-color: #000;
$text-high-contrast-color: #fff;

body {
  …
  @if $high-contrast == true {
    background-color: $background-high-contrast-color;
  } else {
    background-color: $background-color;
  }
  …
}
…
.text {
  @if $high-contrast == true {
    color: $text-color;
  } else {
    color: $text-high-contrast-color;
  }
}

Dies könnte unser CSS etwas kompliziert und schwer zu warten machen. Hier ist eine andere Methode: @mixins

$high-contrast: true;
$background-color: #fff;
$background-high-contrast-color: #000;
$text-color: #000;
$text-high-contrast-color: #fff;

@mixin background-color {
  @if $high-contrast == true {
    background-color: $background-high-contrast-color;
  } @else {
    background-color: $background-color;
  }
}

@mixin text-color {
  @if $high-contrast == true {
    color: $text-high-contrast-color;
  } @else {
    color: $text-color;
  }
}

body {
  …
  @include background-color;
  …
}
…
.text {
  @include text-color;
}

Diese Methode ist etwas besser, hat aber immer noch Nachteile. Es gibt unzählige andere Möglichkeiten, eine High-Contrast-Version zu entwickeln. Jede hat ihre eigenen Vor- und Nachteile.

Aber was, wenn Sie keinen Präprozessor verwenden? Oder was, wenn Ihr Projekt bereits in der Entwicklung ist und Variablen oder Mixins nicht korrekt verwendet werden oder ganz fehlen?

Wir hatten dieses Problem. Während ein Teil des Teams nach High Contrast forschte und nach Wegen suchte, es in den Entwicklungsprozess zu integrieren, entwickelte ein anderer Teil des Teams das Projekt bereits. Außerdem verwendeten sie leider überhaupt keinen Präprozessor.

Eine Plugin-Idee!

Glücklicherweise kannten wir PostCSS und all seine Möglichkeiten bereits. Das Tolle an PostCSS für uns war, dass wir die Eigenschaften oder Werte, die wir brauchten, einfach ändern oder ersetzen konnten, alles andere konnte unberührt bleiben. Ist das nicht großartig? Deshalb haben wir uns entschieden, das PostCSS High Contrast Plugin zu entwickeln.

Entwicklung des PostCSS-Plugins

Zuerst schien es uns wie eine weitere Herausforderung. Niemand hatte die geringste Ahnung, wie man ein PostCSS-Plugin schreibt. Wir waren überrascht, wie einfach es war. PostCSS hat eine großartige Dokumentation und Community, und das ist besonders für Neulinge wie uns sehr hilfreich.

Nach einer Stunde des Durchblätterns der PostCSS-Dokumentation konnten wir mit unserem Plugin beginnen. PostCSS hat eine wirklich großartige API. Schauen Sie sich diese wenigen Zeilen JS an

css.walkRules( function (rule) {
  if (rule.selector === 'body') {
    // do something…
  }
});

Sie sprechen für sich!

Aber dennoch standen wir vor einer Reihe anderer Probleme

  • Welche Farben sollen geändert und welche unverändert bleiben?
  • Was ist, wenn Farben von übergeordneten Elementen geerbt werden?
  • Was ist, wenn Farben bereits High Contrast sind?
  • Was ist, wenn es sich um ein komplexes Element handelt, das nicht so einfach zu modifizieren ist, seine Farbe oder Hintergrundfarbe zu ändern?

Wir hatten viele Fragen. Wir wussten nicht, wie wir weitermachen sollten.

Zuerst mussten wir entscheiden, welche Farben wir ändern und welche wir unverändert lassen. Wir versuchten herauszufinden, ob jede Farbe ausreichend kontrastreich ist oder nicht, indem wir ihre Helligkeit und Sättigung überprüften.

 var declColor = color(decl.value).hsl();    
if (declColor.s > 50 && declColor.l > 50){
  decl.value = '#000';
}

Aber nach einigen Tests dieser Vorgehensweise entschieden wir, dass sie nicht sehr gut für uns geeignet war. Sie war sehr kompliziert, manchmal funktionierte sie nicht wie erwartet und es dauerte länger, unser CSS zu kompilieren. Wir erkannten, dass der beste Weg darin besteht, einfach alle Farben zu ersetzen, egal was passiert.

if (decl.prop === 'background-color') {
  decl.value = #000;
}

if (decl.prop === 'color') {
  decl.value = #fff;
}

Das schien gut zu funktionieren. Nachdem wir unseren weiteren kleinen Sieg gefeiert hatten, bemerkten wir, dass nicht alle Elemente betroffen waren. Die Untersuchung des Problems zeigte, dass nicht alle Elemente Farbeigenschaften haben. CSS-Vererbung! Um dieses Problem zu lösen, entschieden wir uns für einen „aggressiven Modus“.

Der „aggressive Modus“ akzeptiert eine Liste von Selektoren, die unabhängig von allem die Farbeigenschaft erhalten.

postcss([
  require('postcss-high-contrast')({
    aggressiveHC: true,
    aggressiveHCDefaultSelectorList: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'li', 'th', 'td'],
    aggressiveHCCustomSelectorList: ['div', 'span'],
  })
])

Nach einigen weiteren verschiedenen Tests schien unser Plugin fertig zu sein.

Wie funktioniert es?

Bevor ich unsere Geschichte beende, möchte ich beschreiben, wie man das PostCSS High Contrast Plugin verwendet. Ich hoffe, Sie sind bereits mit PostCSS und seinem Ökosystem vertraut. Wenn nicht, besuchen Sie die PostCSS-Website. Egal welche Präferenz Sie für Ihren Präprozessor haben, Sie können PostCSS zusätzlich verwenden. Das bedeutet, dass das PostCSS High Contrast Plugin mit jedem CSS funktioniert.

Hier ist ein Beispiel für eine Konfiguration

postcss([
  require('postcss-high-contrast')({
    aggressiveHC: true,
    aggressiveHCDefaultSelectorList: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'li', 'th', 'td'],
    aggressiveHCCustomSelectorList: ['div', 'span'],

    backgroundColor: '#000',
    altBgColor: '#fff',

    textColor: '#fff',

    linkColor: '#fcff3c',
    linkHoverColor: '#fcff3c',

    borderColor: '#fff',
    disableShadow: true,

    imageFilter: 'invert(100%)',
    imageSelectors: ['img'],

    removeCSSProps: false,
    CSSPropsWhiteList: ['background', 'background-color', 'color', 'border', 'border-top', 'border-bottom',
      'border-left', 'border-right', 'border-color', 'border-top-color', 'border-right-color',
      'border-bottom-color', 'border-left-color', 'box-shadow', 'filter', 'text-shadow']
  })
])

Beispiel im normalen Modus

/* Before */
body {
  background: #fff;
  color: #000;
}

a {
  color: #0b39e1;
}

/* After */
body {
  background: #000;
  color: #fff;
}

a {
  color: #fcff3c;
}

Beispiel im aggressiven Modus

/* Before */
h1 {
  font-size: 48px;
  margin: 0;
  padding: 0 24px;
  width: 100%;
}

p {
  font-size: 48px;
  margin: 0 0 24px;
}

/* After */
h1 {
  color: #fff;
  font-size: 48px;
  margin: 0;
  padding: 0 24px;
  width: 100%;
}

p {
  color: #fff;
  font-size: 48px;
  margin: 0 0 24px;
}

Das Ende

Es war eine großartige Erfahrung für uns, das PostCSS High Contrast Plugin zu entwickeln. Ich möchte dem PostCSS-Team für das großartige Werkzeug, die Dokumentation und die API danken. Wir hätten nie gedacht, dass es so einfach sein würde.

Wir leben in einer wunderbaren Zeit. Wir haben so viele Technologien, die uns jeden Tag helfen, und das Internet ist eines der wichtigsten. Lassen Sie uns also versuchen, es für jeden zugänglicher zu machen.