Card with multiple links and tab-stopping

I'm trying to figure out the best way to navigate through a series of project information cards that include links to a live demo and Github Repo without overwhelming visually impaired users with excessive tab stops. I want the navigation to be seamless for all users, including those who rely on screen readers like NVDA, without relying on JavaScript.

Currently, my code includes two list elements for visual purposes:

<ul>
  <li tabindex="0">
    <h3>Project Name</h3>
    <img src="https://via.placeholder.com/744.png" alt="Preview Image of X project">
    <div>
      <p>
        Project Description
      </p>
      <div>
        <a href="{Link to live page}" target="_blank" tabindex="-1">View Demo</a>
        <a href="{Link to Github Repo}" target="_blank" tabindex="-1">View Code</a>
      </div>
    </div>
  </li>
  <li tabindex="0">
    <h3>Project Name</h3>
    <img src="https://via.placeholder.com/744.png" alt="Preview Image of X project">
    <div>
      <p>
        Project Description
      </p>
      <div>
        <a href="{Link to live page}" target="_blank" tabindex="-1">View Demo</a>
        <a href="{Link to Github Repo}" target="_blank" tabindex="-1">View Code</a>
      </div>
    </div>
  </li>
</ul>

Here is a snapshot of one of the project cards: Project Card Screenshot

Answer №1

There are two approaches to managing cards: making the entire card clickable or allowing individual elements within the card to be clickable. It is not recommended to combine these methods, as it can introduce complications, especially with nested hyperlinks.

Given that there are two distinct links within the cards leading to different destinations, opting for the latter option would be more effective.

Here are some recommendations to improve your HTML structure based on the presence of dual links in the card:

Your current HTML layout is robust, but minor adjustments are necessary.

1. Avoid using tabindex="0" for the entire card.

The use of tabindex="0" to make the entire card focusable serves no real purpose, particularly with multiple internal links, and is redundant.

Remember, it's best to only make elements focusable if they have associated actions, aiding keyboard users without sight impairments.

2. Use descriptive link text.

Clearly labeling links is crucial for screen reader users who rely on them for navigation. Consider providing meaningful descriptions like "Project X Demo" and "View Project X."

You have a couple of options:

  1. Opt for descriptive link text universally, potentially stacking buttons instead of placing them side by side, using labels like "X project Demo" and "View X Project".
  2. Include visually hidden text to offer context to screen reader users.

If possible, prioritize the first approach by adjusting the design to accommodate expanded text.

Additional Link Considerations

As each link should now be accessible, ensure that tabindex="-1" is removed accordingly.

If links open in new windows, consider indicating this behavior to users for clarity.

Including a subtle icon next to such links can signify their functionality, enhancing the user experience.

Implementing a simple CSS technique can automate this process:

a[target="_blank"]::after {
  content: '\29C9';
  content: '\29C9' / " (opens in new window)";
  margin: 0 3px 0 5px;
}

Note the duplication in the content declaration - one for visual display and the other containing alternative text for screen readers.

The chosen character may vary, but its relevance should be maintained effectively.

Does the Image Provide Value?

Analyze whether the image contributes significant information to the page. If not, treat it as decorative. An image adds value when its contents do not convey essential details.

To designate an image as decorative, set the alt attribute to an empty string, ensuring the attribute remains present. For instance, <img alt="" /> is appropriate, while <img alt /> is not as valid. Using alt="" ensures proper image handling by screen readers.

Updated HTML Structure incorporating Visually-Hidden Text Responsibly

Highlighted changes made to the HTML code above aim to enhance accessibility while maintaining visual appeal through CSS techniques.

Utilize CSS guidelines to hide text visually yet retain accessibility for screen reader users.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Changing Background Images Based on Screen Size in CSS Media Queries

Hey there, I am currently using two different header images - one for desktop and another for both tablet and mobile devices. I am wondering how I can automatically switch from the desktop header image to the mobile/tablet header image when the screen siz ...

Discovering when the DOM has finished rendering in AngularJS with ng-repeat

I am looking for a way to trigger an alert or message upon completion of rendering in my HTML DOM using AngularJS, specifically when dealing with multiple ng-repeats. HTML Code: <body> <div ng-controller="Ctrl"> <div ng-repeat= ...

Tips for reducing the impact on performance caused by cookie consent code

Experimenting with basic HTML to analyze the impact of cookie consent code. <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="determine page l ...

Display a specific element only if another element exceeds a specified height

A snippet of HTML code is given below: <span class="day-number">{{day-number}}</span> <div class="event-box"> <div class="event-container"> </div> <div class="more-events">more ...</div> </div> The .e ...

"Trouble encountered while trying to display Angular in an HTML document

In my Angular project, there is a feature where a list of orders is displayed in one view. Each order is represented by its title only. When the user clicks on the title, they should be redirected to a new view showing the complete content of that particul ...

Issue of inconsistency: The element is not connected to the page's document

Although this question may be a duplicate, I have not been able to find a solution for it, which is why I am asking again. I am currently using Selenium with C# and encountering the above error in several tests that involve the same action on the same pag ...

Everything seems to be functioning properly on the local server, but once the media files or players (mp3 and mp4) are uploaded, the background fails to work entirely

function playMusic() { var songs = [ "pump.mp3", "ybwm.mp3", "bb.mp3", ]; var randomIndex = Math.floor(Math.random() * songs.length); var selectedSong = songs[randomIndex]; var audio = new Audio(selecte ...

What steps can I take to completely remove JavaScript from an HTML document?

To eliminate the <script> tags in the HTML, I can utilize regex just like this $html = preg_replace('#<script(.*?)>(.*?)</script>#is','', $html); While this approach works well, dealing with inline JavaScript require ...

Adjust the color of the entire modal

I'm working with a react native modal and encountering an issue where the backgroundColor I apply is only showing at the top of the modal. How can I ensure that the color fills the entire modal view? Any suggestions on how to fix this problem and mak ...

Every time I hover, my jQuery code keeps repeating the hover effect

I am currently facing an issue that has me stumped on finding a solution. The problem arises when I hover over the .div multiple times, the animation just doesn't stop and keeps running continuously. What I aim for is to have the .hidden element fad ...

I am looking to execute a MySQL query using a value entered into a text box

$query="SELECT * FROM table1 where name='Vidya'"; My text field is ready to capture input. <input type='hidden' value='<?php echo $query;?>' id='getsearchquery' name='getsearchquery'> When I ...

What is the name of the scrolling header effect achieved in the following?

I've been seeing a lot of people using a unique header effect lately and I'm curious to learn more about how it's done. Can anyone explain the process behind achieving this effect, what it's called, and if there are any good tutorials a ...

What exactly happened to my buttons when I transition to the mobile display?

Due to time constraints, I decided to save some time by utilizing a CSS template called Horizons created by Templated. This particular CSS template uses Javascript to adjust the layout for mobile devices, causing buttons to switch from inline to block for ...

Endlessly triggering document.execCommand, the JavaScript selectionchange-EventListener seems to have a mind of

I recently implemented an event listener for selectionchange in the following manner: document.addEventListener("selectionchange", function() { highlight(); console.log("selectionchange-triggered"); }, false); After that, I included the code bel ...

What is the best way to apply the addClass method to a list element

I've been searching for a solution to this issue for some time now, and while I believed my code was correct, it doesn't appear to be functioning as expected. HTML <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js ...

Angular: bypassSecurityTrustHtml sanitizer does not render the attribute (click)

I'm facing an issue where a button I rendered is not executing the alertWindow function when clicked. Can anyone help?: app.component.ts: import { Component, ElementRef, OnInit, ViewEncapsulation } from '@angular/core'; import ...

Price Adjuster Tracker

Recently, I coded a small JavaScript program with the purpose of: incrementing or decrementing the quantity of an item by 1 adjusting the price of an item based on the initial price However, my excitement turned to disappointment when I encountered these ...

Unusual behavior exhibited by MUI Grid in the presence of spacing

I am working on a code snippet that looks like this: <Box sx={{height:'100vh', background: '#f5f7fc', overflow:'auto'}}> <Grid container justifyContent={'center'} padding={2}> <Grid item ...

A new URL must be refreshed for the link to properly bind the data received from the API call with the subscribe method

In my Angular application, I have a URL link that fetches data from the backend API using the subscribe method in a component. The expected behavior is that when this URL is accessed in a browser, the data should be displayed in the corresponding HTML comp ...

Encountering an unusual hash code when implementing Google Tag Manager in a Next.js project was

I am currently using Next.js and have added Google Tag Manager through a script <script dangerouslySetInnerHTML={{ __html: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var ...