public-ui / kolibri

The accessible HTML-Standard
https://public-ui.github.io
European Union Public License 1.2
162 stars 33 forks source link

🛹 Feature: `aria-disabled=true`, remove `disabled` and cancel `click`-Event #5975

Closed deleonio closed 7 months ago

deleonio commented 8 months ago

Wir können das native disabled durch aria-disabled ersetzen und damit mehr Komponenten mit deaktiviertem State ausstatten.

Vorteile:

Nachteile:

Todos:

Sonderlocke - steht zur Diskussion?!

Drafts:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>disabled-Drafts</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
  </head>
  <style>
    [aria-disabled] {
      color: #333;
      opacity: 0.75;
    }
    [aria-disabled]:after {
      content: ' (disabled)';
    }
  </style>
  <body>
    <h1>disabled-Szenarios</h1>
    <p>
      Using Aria-Disabled, we can implement more scenarios with deactivated
      status without barriers.
    </p>
    <hr aria-hidden="true" />
    <a aria-disabled="true" class="disabled" href="#">Link-Text</a>
    <hr aria-hidden="true" />
    <button aria-disabled="true" class="disabled">Button-Text</button>
    (regulär
    <button class="disabled" tabindex="0" disabled>Button-Text</button>)
    <hr aria-hidden="true" />
    <details aria-expanded="false" class="disabled">
      <summary aria-disabled="true">Closed Details</summary>
      Text
    </details>
    <br />
    <details aria-expanded="true" class="disabled" open>
      <summary aria-disabled="true">Open Details</summary>
      Text
    </details>
    <hr aria-hidden="true" />
    <div class="accordion disabled">
      <h2>
        <button
          aria-disabled="true"
          aria-control="content-0"
          aria-expanded="false"
          class="disabled"
          id="headline-0"
        >
          Closed Accodrion
        </button>
      </h2>
      <div
        aria-labelledby="headline-0"
        aria-hidden="true"
        hidden
        id="content-0"
      >
        Content
      </div>
    </div>
    <br />
    <div class="accordion disabled">
      <h2>
        <button
          aria-disabled="true"
          aria-control="content-1"
          aria-expanded="true"
          class="disabled"
          id="headline-1"
        >
          Open Accodrion
        </button>
      </h2>
      <div aria-labelledby="headline-1" aria-hidden="false" id="content-1">
        Content
      </div>
    </div>
    <hr aria-hidden="true" />
    <label>
      Input (aria-disabled + readonly)
      <!-- cancel input with readonly -->
      <input aria-disabled="true" readonly value="Value" />
    </label>
    <br />
    <label>
      Input (readonly)
      <input readonly value="Value" />
    </label>
    <br />
    <label>
      Input (disabled)
      <input disabled value="Value" />
    </label>
    <hr aria-hidden="true" />
    <label>
      Select (aria-disabled + ???)
      <!-- cancel open with ??? -->
      <select aria-disabled="true">
        <option>Value 1</option>
        <option>Value 2</option>
        <option>Value 3</option>
      </select>
    </label>
    <br />
    <label>
      Select (disabled)
      <select disabled>
        <option>Value 1</option>
        <option>Value 2</option>
        <option>Value 3</option>
      </select>
    </label>
    <hr aria-hidden="true" />
    <label>
      Textarea (aria-disabled + readonly)
      <!-- cancel input with readonly -->
      <textarea aria-disabled="true" readonly>Text</textarea>
    </label>
    <br />
    <label>
      Textarea (readonly)
      <textarea readonly>Text</textarea>
    </label>
    <br />
    <label>
      Textarea (disabled)
      <textarea disabled>Text</textarea>
    </label>
    <script>
      function cancelClick(e) {
        // caution
        if (e.key !== 'Tab') {
          e.preventDefault();
          console.log(e);
        }
      }
      Array.from(document.querySelectorAll('[aria-disabled="true"]')).forEach(
        (el) => {
          el.addEventListener('click', cancelClick);
          el.addEventListener('keydown', cancelClick);
          el.addEventListener('mousedown', cancelClick);
        }
      );
    </script>
  </body>
</html>

Feedback:

deleonio commented 8 months ago

FYI @Sommerli2, @fohi17, @cbraehmig, @ElVariablo, @sdvg, @laske185

Ich habe es mal prototypisch umgesetzt, man müsste natürlich das CSS noch für das Szenario anpassen.

Lösung:

Demo:

PS: Leaving the comfort zone.

fohi17 commented 8 months ago

Ich finde den Weg gar nicht so schlecht, wenn die disabled-Varianten angeboten werden müssen. Zumindest mit dem Screenreader funktioniert das so Wunderbar.

Aus meiner Sicht muss die Doku dann eben die Probleme die man sich mit disabled-Elementen evtl. einhandelt genau beschreiben. Diese bestehen ja unabhängig von der Umsetzung mit aria-disabled und tabindex, wie dass der Kontrast zu gering ist (z.B. Buttons, Accordion), oder man nicht sieht was disabled ist (z.B. Details).

sdvg commented 8 months ago

Ich finde den Lösungsansatz auch gut, so wie bisher umgesetzt: Wo möglich weiter disabled verwenden, bei Spezialfällen wie Links auf aria-disabled zurückgreifen 👍 Zur Implementierung habe ich einen Kommentar im PR hinterlassen.

Sommerli2 commented 8 months ago

Ich finde es auch gut, wenn man die Doku an dieser Stelle erweitert. Wenn man schon disabled Elemente verwenden will, welche Informationstragenden Inhalt bereitstellen, dann soll die Variante mit sichtbarer Beschriftung gewählt werden. Mit der Empfehlung nicht mit Disabled zu arbeiten.