Technique C43:Using CSS margin
and scroll-margin
to un-obscure content
Description
The objective of this technique is to ensure that user interface components (for example:
links, buttons, and form fields) that are initially completely obscured by a fixed-position
component can still be accessed by users. In this example, this is achieved using
the CSS margin
and scroll-margin
properties to create space underneath the site footer and allow the link in the footer
to scroll into view when it is focused with a keyboard.
Examples
Example 1: Using CSS margin and scroll-margin to un-obscure content
This example shows a situation where there is a fixed-position banner at the bottom of the screen that is covering up the site footer, which contains a link. This type of fixed-position banner is a common design for cookie-consent banners.
Working example: Using CSS margin
and scroll-margin
to un-obscure content.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Using CSS margin and scroll-margin to un-obscure content</title>
<style>
...
.wrapper {
display:grid;
gap:1rem;
grid-template-columns:repeat(9, 1fr);
grid-template-rows:8rem auto minmax(10rem, max-content);
height:100vh;
}
.wrapper > * {
border:1px solid var(--black);
padding:1rem;
}
header {
grid-column:1 / -1;
grid-row:1;
}
main {
grid-column:1 / 8;
}
aside {
grid-column:8 / 10;
}
footer {
grid-column:1 / -1;
}
@media (max-width:70rem) {
main {
grid-column:1 / -1;
}
aside {
grid-column:1 / -1;
}
}
.fixed-position-banner {
background:var(--banner-background);
border:3px solid var(--banner-border);
height:12rem;
inset-block-end:0;
margin-block-end:1rem;
padding:1rem;
position:relative;
width:calc(100vw - 1rem);
}
@media (min-width:70rem), (min-height:60rem) {
.fixed-position-banner {
margin-block-end:0;
position:fixed;
}
.banner-open {
margin-block-end:14rem;
}
.banner-open footer a {
scroll-margin-block-end:15.5rem;
}
}
</style>
</head>
<body>
<dialog class="fixed-position-banner">
<h2 tabindex="-1">Fixed-Position Banner</h2>
<button aria-label="close fixed-position banner" class="close-banner" type="button">
...
</button>
</dialog>
<div class="wrapper">
<header>
<p>Header Content</p>
</header>
<main>
<h1>Main Content</h1>
</main>
<aside>
<h2>Sidebar Content</h2>
</aside>
<footer>
<h2>Footer Content</h2>
<p><a href="https://example.com">Here's an example link in the footer</a>.</p>
</footer>
</div>
<script>
document.addEventListener("DOMContentLoaded", function(e){
const cookieBanner = document.querySelector(".fixed-position-banner");
const closeBannerBtn = document.querySelector(".close-banner");
const pageBody = document.querySelector("body");
cookieBanner.show();
if(cookieBanner.hasAttribute("open")){
pageBody.classList.add("banner-open");
}
closeBannerBtn.addEventListener("click", function(e){
cookieBanner.close();
pageBody.classList.remove("banner-open");
}, false);
});
</script>
</body>
</html>
Applicability
All technologies that support CSS.
Tests
Procedure
For each user interface component that can receive keyboard focus:
- Check that the user interface component is not entirely hidden when it receives keyboard focus.
Expected Results
- Check 1 is true.