Skip to content

Commit 04c87a5

Browse files
committed
Initial commit of C43
1 parent 792b7ee commit 04c87a5

File tree

1 file changed

+269
-0
lines changed

1 file changed

+269
-0
lines changed

techniques/css/C43.html

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
<!DOCTYPE html>
2+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
3+
<head>
4+
<title>Using CSS margin and scroll-margin to un-obscure content</title>
5+
<link rel="stylesheet" type="text/css" href="../../css/editors.css"/>
6+
</head>
7+
<body>
8+
<h1>Using <abbr title="Cascading Style Sheets">CSS</abbr> <code class="language-css">margin</code> and <code class="language-css">scroll-margin</code> to un-obscure content</h1>
9+
<section id="meta">
10+
<h2>Metadata</h2>
11+
<p id="id"></p>
12+
<p id="technology">CSS</p>
13+
<p id="type"></p>
14+
</section>
15+
<section id="applicability">
16+
<h2>When to Use</h2>
17+
<p>All technologies that support CSS.</p>
18+
</section>
19+
<section id="description">
20+
<h2>Description</h2>
21+
<p>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 <code class="language-css">margin</code> and <code class="language-css">scroll-margin</code> 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.</p>
22+
</section>
23+
<section id="examples">
24+
<h2>Examples</h2>
25+
26+
<section class="example">
27+
<h3>Using CSS margin and scroll-margin to un-obscure content</h3>
28+
<p>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.</p>
29+
<pre><code>&lt;!doctype html&gt;
30+
&lt;html lang="en"&gt;
31+
&lt;head&gt;
32+
&lt;meta charset="utf-8"&gt;
33+
&lt;meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"&gt;
34+
&lt;title&gt;Using CSS margin and scroll-margin to un-obscure content&lt;/title&gt;
35+
&lt;style&gt;
36+
:root{
37+
font-size:100%;
38+
box-sizing:border-box;
39+
--banner-background:hsl(60,80%,90%);
40+
--banner-border:hsl(0, 0%, 50%);
41+
--default-focus-indicator:hsl(234, 72%, 42%);
42+
--fixed-banner-focus-indicator:black;
43+
}
44+
45+
*, *::after, *::before{
46+
box-sizing:inherit;
47+
}
48+
49+
body{
50+
background:white;
51+
color:black;
52+
font:1rem/1.5 system-ui, "Segoe UI", Roboto, Helvetica, sans-serif;
53+
margin:0;
54+
}
55+
56+
h1, h2, h3, h4, h5, h6{
57+
font-weight:500;
58+
}
59+
60+
.wrapper{
61+
display:grid;
62+
gap:1rem;
63+
grid-template-columns:repeat(9, 1fr);
64+
grid-template-rows:8rem auto minmax(10rem, max-content);
65+
height:100vh;
66+
}
67+
68+
.wrapper > *{
69+
border:1px solid black;
70+
padding:1rem;
71+
}
72+
73+
.wrapper :focus-visible{
74+
outline:2px solid transparent;
75+
box-shadow:0 5px 0 0 var(--default-focus-indicator);
76+
}
77+
78+
header{
79+
align-items:center;
80+
display:flex;
81+
font-size:1.5rem;
82+
font-weight:bold;
83+
grid-column:1 / -1;
84+
grid-row:1;
85+
}
86+
87+
main{
88+
grid-column:1 / 8;
89+
}
90+
91+
aside{
92+
grid-column:8 / 10;
93+
}
94+
95+
footer{
96+
grid-column:1 / -1;
97+
}
98+
99+
@media (max-width:70rem){
100+
main{
101+
grid-column:1 / -1;
102+
}
103+
104+
aside{
105+
grid-column:1 / -1;
106+
}
107+
}
108+
109+
.fixed-position-banner{
110+
background:var(--banner-background);
111+
border:3px solid var(--banner-border);
112+
bottom:0;
113+
height:12rem;
114+
margin-bottom:1rem;
115+
padding:1rem;
116+
position:relative;
117+
width:calc(100vw - 1rem);
118+
}
119+
120+
.fixed-position-banner a{
121+
outline-color:var(--fixed-banner-focus-indicator);
122+
}
123+
124+
.fixed-position-banner h2{
125+
display:inline-block;
126+
margin-block-start:0;
127+
padding:0.25em;
128+
}
129+
130+
.fixed-position-banner h2:focus-visible{
131+
outline:2px solid var(--fixed-banner-focus-indicator);
132+
}
133+
134+
@media (min-width:70rem), (min-height:60rem){
135+
.fixed-position-banner{
136+
margin-bottom:0;
137+
position:fixed;
138+
}
139+
140+
.banner-open{
141+
margin-bottom:14rem;
142+
}
143+
144+
.banner-open footer a{
145+
scroll-margin-bottom:15.5rem;
146+
}
147+
}
148+
149+
.close-banner{
150+
background:hsl(0, 0%, 100%);
151+
border:1px solid hsl(0, 0%, 50%);
152+
border-radius:3px;
153+
cursor:pointer;
154+
font:inherit;
155+
margin:0;
156+
padding:0.33em;
157+
position:absolute;
158+
right:1rem;
159+
top:1rem;
160+
}
161+
162+
.close-banner-icon{
163+
display:block;
164+
height:1rem;
165+
stroke:currentColor;
166+
width:1rem;
167+
}
168+
169+
.close-banner:focus-visible{
170+
outline:2px solid var(--fixed-banner-focus-indicator);
171+
outline-offset:2px;
172+
}
173+
&lt;/style&gt;
174+
&lt;/head&gt;
175+
&lt;body&gt;
176+
&lt;dialog class="fixed-position-banner"&gt;
177+
&lt;h2 tabindex="-1"&gt;Fixed-Position Banner&lt;/h2&gt;
178+
&lt;button aria-label="close fixed-position banner" class="close-banner" type="button"&gt;
179+
&lt;svg aria-hidden="true" class="close-banner-icon" role="img" viewbox="0 0 16 16"&gt;
180+
&lt;line x1="0" y1="0" x2="15" y2="15" /&gt;
181+
&lt;line x1="0" y1="15" x2="15" y2="0" /&gt;
182+
&lt;/svg&gt;
183+
&lt;/button&gt;
184+
&lt;/dialog&gt;
185+
&lt;div class="wrapper"&gt;
186+
&lt;header&gt;
187+
&lt;p&gt;Header Content&lt;/p&gt;
188+
&lt;/header&gt;
189+
&lt;main&gt;
190+
&lt;h1&gt;Main Content&lt;/h1&gt;
191+
&lt;/main&gt;
192+
&lt;aside&gt;
193+
&lt;h2&gt;Sidebar Content&lt;/h2&gt;
194+
&lt;/aside&gt;
195+
&lt;footer&gt;
196+
&lt;h2&gt;Footer Content&lt;/h2&gt;
197+
&lt;p&gt;&lt;a href="https://example.com"&gt;Here&#39;s an example link in the footer&lt;/a&gt;.&lt;/p&gt;
198+
&lt;/footer&gt;
199+
&lt;/div&gt;
200+
&lt;script&gt;
201+
document.addEventListener(&quot;DOMContentLoaded&quot;, function(e){
202+
const cookieBanner = document.querySelector(&quot;.fixed-position-banner&quot;);
203+
const closeBannerBtn = document.querySelector(&quot;.close-banner&quot;);
204+
const pageBody = document.querySelector(&quot;body&quot;);
205+
206+
cookieBanner.show();
207+
208+
if(cookieBanner.hasAttribute(&quot;open&quot;)){
209+
pageBody.classList.add(&quot;banner-open&quot;);
210+
}
211+
212+
closeBannerBtn.addEventListener(&quot;click&quot;, function(e){
213+
cookieBanner.close();
214+
pageBody.classList.remove(&quot;banner-open&quot;);
215+
}, false);
216+
});
217+
&lt;/script&gt;
218+
&lt;/body&gt;
219+
&lt;/html&gt;</code></pre>
220+
221+
<aside class="note">
222+
<p>Due to the current lack of cross-browser support for the the CSS <code class="language-css">:has</code> pseudo-class, this example uses JavaScript to create the <code class="language-css">margin</code> at the bottom of the page. Using the <code class="language-css">:has</code> selector, the relevant CSS is:</p>
223+
<pre><code>body:has(.fixed-position-banner[open]){
224+
margin-bottom:14rem;
225+
}
226+
227+
body:has(.fixed-position-banner[open]) footer a{
228+
scroll-margin-bottom:15.5rem;
229+
}</code></pre>
230+
</aside>
231+
</section>
232+
</section>
233+
234+
<section id="tests">
235+
<h2>Tests</h2>
236+
<section class="test-procedure">
237+
<h3>Procedure</h3>
238+
239+
<p>For each user interface component that entirely hidden by author-created content and receives keyboard focus:</p>
240+
<ol>
241+
<li>Check that the user interface component becomes not entirely hidden when it receives keyboard focus.</li>
242+
</ol>
243+
</section>
244+
<section class="test-results">
245+
<h3>Expected Results</h3>
246+
<ul>
247+
<li>Check 1 is true.</li>
248+
</ul>
249+
</section>
250+
</section>
251+
<section id="related">
252+
<h2>Related Techniques</h2>
253+
<ol>
254+
<li><a href="C32">C32</a></li>
255+
<li><a href="C34">C34</a></li>
256+
</ol>
257+
258+
</section>
259+
<section id="resources">
260+
<h2>Resources</h2>
261+
<ol>
262+
<li><a href="https://www.w3.org/TR/css-box/#margins"><abbr title="World Wide Web Consortium">W3C</abbr> - CSS margins</a></li>
263+
<li><a href="https://www.w3.org/TR/css-scroll-snap/#scroll-margin">W3C - CSS the <code class="language-css">scroll-margin</code> property</a>.</li>
264+
<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:has"><abbr title="Mozilla Developer Network">MDN</abbr> - <code class="language-css">:has()</code> property</a>.</li>
265+
</ol>
266+
267+
</section>
268+
</body>
269+
</html>

0 commit comments

Comments
 (0)