Technique C43:Using CSS margin
and scroll-margin
to un-obscure content
Applicability
All technologies that support CSS.
This technique is not referenced from any Understanding document.
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>
Other sources
No endorsement implied.
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.