Elemento Focável Aninhado

This page is not available in the language you requested. You have been redirected to the English version of the page.
Link to this page copied to clipboard

Não roube o foco de um elemento pai clicável tornando um elemento filho focável

Not for use with personal data

WCAG 2.1 - 4.1.2 A Impact - Critical

O Que Verificamos

Elementos focáveis não devem estar aninhados dentro de elementos pais clicáveis. Quando um elemento filho não interativo é focável, a tecnologia assistiva foca nele em vez do pai clicável — o que significa que o papel interativo do elemento nunca é anunciado.

Esta regra verifica todos os controles focáveis em termos de acessibilidade que não são interativos por si mesmos. Se tal controle estiver contido em um elemento pai clicável, ele é inerentemente interativo, mas não anunciará um papel. O elemento será sinalizado como uma violação de acessibilidade.

Exemplo de Falha ❌

Contact card for Sarah Anderson. The outer card has a red border and the nested profile picture section has a blue TalkBack focus ring, showing the inner element stealing focus from the clickable card.

O cartão é clicável, mas a foto do perfil dentro dele é focável separadamente.

TalkBack não anuncia o papel do cartão ou a dica de "Toque duas vezes para ativar", e em vez disso foca e anuncia o elemento interno.

Os usuários não sabem que o cartão é interativo, e o elemento com foco não é clicável.

Exemplo de Sucesso ✅

Contact card for Sarah Anderson with a single blue TalkBack focus ring around the entire card, showing proper focus on the clickable element.

O elemento interno não é mais focável separadamente.

TalkBack foca no próprio cartão e anuncia seu conteúdo, papel e "Toque duas vezes para ativar".

Os usuários entendem que o cartão é interativo e podem ativá-lo.

Em Resumo

  • Esta regra tem um impacto Crítico para usuários do TalkBack e do Voice Access
  • Quando um elemento filho rouba o foco de um pai clicável, o papel interativo é perdido
  • O TalkBack não anunciará "Toque duas vezes para ativar" se o elemento focado não for ele mesmo clicável
  • A solução é sempre remover a focabilidade do elemento aninhado, e não adicionar um papel a ele
  • Visualizações de contêineres que não têm ação não devem ser deixadas clicáveis — isso evita falsos positivos

Impacto para os Usuários

Quando a tecnologia assistiva não anuncia um papel, usuários cegos ou com baixa visão que dependem do TalkBack não saberão que podem disparar uma ação. Por exemplo, o TalkBack foca em um elemento interno e anuncia apenas seu texto (ex.: "Tema"). Ele não anuncia que é um botão, ou que o usuário deve tocar duas vezes para ativar. Os usuários ficam sem o contexto necessário para interagir com a tela.

Confirmar Problema de Elemento Focável Aninhado

  1. Ative o TalkBack
  2. Foque no elemento e em cada um de seus descendentes
  3. Uma das seguintes coisas acontecerá:
    • Inacessível: O TalkBack lê o texto mas não anuncia um papel ou capacidade de interação
    • Acessível: O TalkBack lê todo o texto e também anuncia um papel e/ou como interagir com o elemento

Corrigir Problemas

Remova a focabilidade de elementos aninhados para que o pai clicável possa ganhar foco e anunciar seu papel. Não adicione propriedades focáveis a descendentes não interativos de uma visualização clicável.

tip

Para evitar um falso positivo, certifique-se de que elementos contêiner que não fazem nada quando tocados não sejam deixados clicáveis. Nossas ferramentas não podem determinar se um elemento clicável tem uma ação programada associada, então devemos assumir que sim, a fim de sinalizar um comportamento potencialmente inacessível.

Examine elementos contêiner circundantes, como Frame Layouts, Card Views ou Gavetas, para garantir que qualquer elemento sem uma ação associada não seja configurado como clicável.

XML

No exemplo abaixo, o MaterialCardView é clicável, mas se uma das crianças - LinearLayout ou TextView - tiver focusable="true", o TalkBack focará nela em vez do cartão. Em seu estado padrão, a propriedade focusable de ambos LinearLayout e TextView é falsa. Certifique-se de que não está configurada como verdadeira, para que o cartão possa ganhar foco e anunciar seu papel interativo.

<com.google.android.material.card.MaterialCardView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clickable="true">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/contact_name"/>

    </LinearLayout>

</com.google.android.material.card.MaterialCardView>

Compose

Neste exemplo, o Card é clicável, mas se uma das crianças - Row ou Text - tiver um atributo .focusable(), o TalkBack focará nela em vez disso. Certifique-se de que Row ou Text não tenha um atributo .focusable(), para que o Card possa ganhar foco, anunciar seu conteúdo de texto e transmitir seu papel interativo (ex.:"Toque duas vezes para ativar").

Card(
    modifier = Modifier
        .clickable {
            openContact(context)
        }
) {
    Row(
        modifier = Modifier
            .padding(10.dp),
        horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally)
    ) {
        Text("Sarah Anderson")
    }
}

.NET MAUI

No exemplo abaixo, o cartão de contato Grid tem um TapGestureRecognizer para abrir o contato. Se um elemento filho dentro do Grid for focável independentemente, o TalkBack focará nele em vez do cartão. Certifique-se de que nenhum elemento filho tenha AutomationProperties.IsInAccessibleTree="true" configurado explicitamente, para que o Grid mantenha o foco e possa anunciar "Toque duas vezes para ativar".

<Grid
    HorizontalOptions="FillAndExpand"
    RowDefinitions="Auto,Auto"
    RowSpacing="10"
    VerticalOptions="FillAndExpand">

    <Grid.GestureRecognizers>
        <TapGestureRecognizer Command="{Binding OpenContactCommand}"/>
    </Grid.GestureRecognizers>

    <Label
        Grid.Row="1"
        FontAttributes="Bold"
        FontSize="16"
        HorizontalOptions="CenterAndExpand"
        VerticalOptions="FillAndExpand">
        <Label.FormattedText>
            <FormattedString>
                <Span Text="Sarah Anderson"/>
            </FormattedString>
        </Label.FormattedText>
    </Label>
</Grid>

React Native

Neste exemplo, o cartão de contato é um TouchableOpacity com propriedades de acessibilidade configuradas diretamente nele. As propriedades accessible={true} e accessibilityRole="button" garantem que o TalkBack anuncie o cartão como um elemento interativo. Nenhuma visualização filha dentro dele deve ter accessible={true} configurado de forma independente, o que faria com que elas roubassem o foco do cartão.

<TouchableOpacity
    accessible={true}
    accessibilityRole="button"
    style={styles.contactCard}
    onPress={() => openContact("sarah-anderson")}
>
    <Text>Sarah Anderson</Text>
    <Text>sarah@example.com</Text>
</TouchableOpacity>

Flutter

Neste exemplo, o cartão de contato é um Card com um InkWell lidando com o toque. Se um widget filho dentro do Card tiver seu próprio Semantics envolvente com button: true ou onTap configurado, o TalkBack focará nele em vez do cartão. Mantenha o manipulador de toque no InkWell e certifique-se de que nenhum widget descendente reivindique foco de forma independente.

Card(
  child: InkWell(
    onTap: () => openContact(context, "sarah-anderson"),
    child: const Padding(
      padding: EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text("Sarah Anderson"),
          Text("sarah@example.com"),
        ],
      ),
    ),
  ),
)

Posso Ignorar Esta Regra?

Elemento Focável Aninhado tem um impacto crítico para os usuários, e recomendamos fortemente corrigir este problema. Quando o foco está em um elemento não interativo dentro de um pai clicável, os usuários do TalkBack não têm como saber que o elemento pode ser ativado. Ignorar esta regra significa que esses usuários efetivamente não podem interagir com o elemento afetado. Saiba mais sobre regras de ignorar.

Recursos

Páginas do Curso da Deque University

Nota: Acesso completo aos recursos da Deque University requer uma assinatura.

Outros Recursos