【问题标题】:Accessibility with complex custom components复杂自定义组件的可访问性
【发布时间】:2021-07-27 13:30:01
【问题描述】:

可访问性指南是在组件发布之前发明的,所以他们总是说标签用于标识 <input><textarea> 等表单控件。当我有一个复杂的 Angular / React / .. . 像表单控件一样的组件?

想象一个<custom-select> 呈现输入并将项目添加到列表中。生成的 html 如下所示:

<custom-select ....>
  <input ...>
</custom-select>

当我在输入中输入内容并按 Enter 键时,它会将该条目添加到列表中并再次呈现输入,例如:

<custom-select ....>
  <span>What I typed</span>
  <input ...>
</custom-select>

当然,如果我在输入中输入其他内容并按下回车键,它就会被添加到列表中:

<custom-select ....>
  <span>What I typed</span>
  <span>Something else</span>
  <input ...>
</custom-select>

如果我们想在表单中使用这个自定义组件,我们希望像任何其他表单项一样为其添加标签,p.e:

<label for="foo">Foo</label>
<input id="foo" type="text">

<label for="select">Select a country</label>
<custom-select id="select"></custom-select>

这甚至是有效的 a11y 吗? Wave 工具会抱怨孤儿标签,而 ax 什么也没说。那么,我们可以使用普通的旧label 来标记自定义组件以实现可访问性目的吗?我们需要在此处放置标签以保持一致性,但需要可访问。

如果我能做到这一点,custom-select 也会呈现一个输入。该输入需要自己的标签或 aria-label,对吗?

【问题讨论】:

    标签: html reactjs angular accessibility


    【解决方案1】:

    至少在角度上:您可以像下面这样保留 a11y:

    // Custom Input HTML (Using Angular Material for eg);
    
    // You can import the label inside the custom component and bind it to the 
    input field so that you can always have a new ID to every custom input
    
    <mat-form-field [attr.aria-labelledby]="customAriaLabelledByIDs">
      <mat-label *ngIf="label" [for]="customId">{{ label }}</mat-label>
      <input matInput [id]="customId" />
    </mat-form-field>
    
    
    // In your component.ts file, 
    @Input() customId: string;
    @Input() customAriaLabelledByIDs: string[];
    combinedAriaLabelledByIDs: string;
    
    ngOnInit() {
    if (this.customAriaLabelledByIDs) {
          this.combinedAriaLabelledByIDs = 
            this.customAriaLabelledByIDs.length === 1
              ? this.customAriaLabelledByIDs[0]
              : this.customAriaLabelledByIDs.join(' ');
        }
    }
    
    
    
    /// Wherever you use, now you will have something like this: 
    
    <your-custom-selector
         [customAriaLabelledByIDs]="['id-1', 'id-2', 'id-3']"
         [customId]="first-name-ID"
    ></your-custom-selector>
    
    
    <your-custom-selector
         [customAriaLabelledByIDs]="['id-4', 'id-5', 'id-6']"
         [customId]="second-name-ID"
    ></your-custom-selector>
    
    etc.,
    
    

    您可以将多个 aria-attributes 添加到 @Input() 并从自定义组件中使用它,例如 aria-label、role、aria-expanded 等...

    如果您需要对我上面提到的任何事情进行更多解释,请告诉我。很乐意提供帮助!

    【讨论】:

      【解决方案2】:

      是的,输入需要被标记。

      组件是否有任何理由不管理这个?接受标签文本,然后为标签和输入对呈现正确的可访问 HTML?

      所以在 React 中:

      <CustomSelect labelText="Enter your destination" />
      

      组件在做:

      const id = generatedUniqueId() // This will need to be memoized in the real implementation to avoid creating new id's with every render.
      
      ...
      
      <>
      <label for={id}>{labelText}</label>
      <input id={id} />
      </>
      
      
      

      【讨论】:

      • 据我了解,真正的问题不是如何将标签附加到输入。这很清楚。真正的问题是如何保留外部&lt;label for="select"... 以语义附加到&lt;custom-select id="select"&gt;&lt;/custom-select&gt; 保留可访问性,无论它在内部做什么。此外,在组件内部,它可以是 0(只读)、1 或 N 个输入字段,具体取决于组件的状态。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      • 1970-01-01
      • 1970-01-01
      • 2014-12-09
      • 2014-06-30
      • 2018-05-20
      相关资源
      最近更新 更多