cssaccessibilitywcagkeyboard-navigation

accessibility when focused link is hidden behind a fixed-position footer when using TAB to proceed


I ran into a detail concerning accessibility, not in regard to screenreaders and blind users, but in regard to pure keyboard navigation.


Edit / Addition: I would like to emphasize a part of my question which hasn't been addressed at all in the two answers I got until now: I wonder if the situation given in my snippet can be considered accessible, i.e. would conform to accessibility standards?


I have a list of blog posts on a page whose titles are linked to the actual (single) posts - standard blog behaviour. Now, when someone uses the TAB key to navigate and to proceed from one link/blog header to the next, the page will always scroll automatically to show the focused link inside the visible part of the page.

But if I have a fixed footer (same goes for header), at some point the focused link will be hidden by the footer. I am NOT talking about the last few lines on the page! Try the snippet below: Click on one of the visible links to focus it, then use the TAB key to jump to the next, then the next and so on: At some point, the focused link will be behind the footer. Same when I go back (using shift + tab) after the page has already scrolled down: At some point the focused link is behind the fixed header.

Setting a top and bottom padding or margin doesn't help in this case...

I know it is possible to manually scroll down using the arrow keys, but first of all I wonder if this can still be considered fully accessible, and apart from that I simply wonder if there is anything to make the browser scroll the focused element into the visible part of the element it's in?

html,
body {
  margin: 0;
  height: 100%;
}
ul {
  padding: 40px 0 80px;
}
li {
  font-size: 24px;
  padding: 10px;
}

header {
  position: fixed;
  top: 0;
  height: 40px;
  width: 100%;
  background: rgba(33, 233, 158, 1);
  text-align: center;
}

footer {
  position: fixed;
  bottom: 0;
  height: 80px;
  width: 100%;
  background: rgba(33, 233, 158, 0.8);
  text-align: center;
}

footer p {
  padding: 0 60px;
}

a:focus {
  background: red;
}
<header>This is a fixed header</header>
<ul>
  <li><a href="#">link to blogpost 1</a></li>
  <li><a href="#">link to blogpost 2</a></li>
  <li><a href="#">link to blogpost 3</a></li>
  <li><a href="#">link to blogpost 4</a></li>
  <li><a href="#">link to blogpost 5</a></li>
  <li><a href="#">link to blogpost 6</a></li>
  <li><a href="#">link to blogpost 7</a></li>
  <li><a href="#">link to blogpost 8</a></li>
  <li><a href="#">link to blogpost 9</a></li>
  <li><a href="#">link to blogpost 10</a></li>
  <li><a href="#">link to blogpost 11</a></li>
  <li><a href="#">link to blogpost 12</a></li>
  <li><a href="#">link to blogpost 13</a></li>
  <li><a href="#">link to blogpost 14</a></li>
  <li><a href="#">link to blogpost 15</a></li>
  <li><a href="#">link to blogpost 16</a></li>
  <li><a href="#">link to blogpost 17</a></li>
  <li><a href="#">link to blogpost 18</a></li>
  <li><a href="#">link to blogpost 19</a></li>
  <li><a href="#">link to blogpost 20</a></li>
  <li><a href="#">link to blogpost 21</a></li>
  <li><a href="#">link to blogpost 22</a></li>
  <li><a href="#">link to blogpost 23</a></li>
  <li><a href="#">link to blogpost 24</a></li>
</ul>
<footer>
  <p>This is a fixed footer<br>The slight transparency of the background color is only used to show what is behind it - on a real website the background would be a non-transparent color.</footer>


Solution

  • You can use simply CSS to solve this. There is a scroll-margin property which is also applied when the browser automatically scrolls to the focused element.

    html,
    body {
      margin: 0;
      height: 100%;
    }
    ul {
      padding: 40px 0 80px;
    }
    li {
      font-size: 24px;
      padding: 10px;
    }
    
    header {
      position: fixed;
      top: 0;
      height: 40px;
      width: 100%;
      background: rgba(33, 233, 158, 1);
      text-align: center;
    }
    
    footer {
      position: fixed;
      bottom: 0;
      height: 80px;
      width: 100%;
      background: rgba(33, 233, 158, 0.8);
      text-align: center;
    }
    
    footer p {
      padding: 0 60px;
    }
    
    a:focus {
      scroll-margin: 40px 0 80px; /* header's and footer's height */
      background: red;
    }
    <header>This is a fixed header</header>
        <ul>
          <li><a href="#">link to blogpost 1</a></li>
          <li><a href="#">link to blogpost 2</a></li>
          <li><a href="#">link to blogpost 3</a></li>
          <li><a href="#">link to blogpost 4</a></li>
          <li><a href="#">link to blogpost 5</a></li>
          <li><a href="#">link to blogpost 6</a></li>
          <li><a href="#">link to blogpost 7</a></li>
          <li><a href="#">link to blogpost 8</a></li>
          <li><a href="#">link to blogpost 9</a></li>
          <li><a href="#">link to blogpost 10</a></li>
          <li><a href="#">link to blogpost 11</a></li>
          <li><a href="#">link to blogpost 12</a></li>
          <li><a href="#">link to blogpost 13</a></li>
          <li><a href="#">link to blogpost 14</a></li>
          <li><a href="#">link to blogpost 15</a></li>
          <li><a href="#">link to blogpost 16</a></li>
          <li><a href="#">link to blogpost 17</a></li>
          <li><a href="#">link to blogpost 18</a></li>
          <li><a href="#">link to blogpost 19</a></li>
          <li><a href="#">link to blogpost 20</a></li>
          <li><a href="#">link to blogpost 21</a></li>
          <li><a href="#">link to blogpost 22</a></li>
          <li><a href="#">link to blogpost 23</a></li>
          <li><a href="#">link to blogpost 24</a></li>
        </ul>
        <footer>
          <p>
            This is a fixed footer<br />The slight transparency of the background
            color is only used to show what is behind it - on a real website the
            background would be a non-transparent color.
          </p>
        </footer>