Skip to content

Commit 330d2c7

Browse files
committed
Merge branch 'refs/heads/main' into feature/update-logo
2 parents 8942cf9 + 2adf802 commit 330d2c7

File tree

13 files changed

+309
-3
lines changed

13 files changed

+309
-3
lines changed

assets-src/js/main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {navigation} from "./main/navigation";
77
import {responsiveTables} from "./main/responsive-tables";
88
import {flashes} from "./main/flashes";
99
import {headingAnchors} from './main/heading-anchors';
10+
import {videoHero} from './main/video-hero';
1011

1112
function domLoadedActions() {
1213
accountMenu();
@@ -17,6 +18,7 @@ function domLoadedActions() {
1718
responsiveTables();
1819
flashes();
1920
headingAnchors();
21+
videoHero();
2022

2123
/* Create a navDoubleLevel object and initiate double-level navigation for a <ul> with the correct data-component attribute */
2224
const navDoubleIntro = document.querySelector('ul[data-component="nav-double-intro"]');

assets-src/js/main/video-hero.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
let videoHero = function () {
2+
/* My refactored code */
3+
var heroVid = document.querySelector('[data-video="hero"]');
4+
var heroVidControl = document.querySelector('[data-video-control="hero"]');
5+
6+
if (heroVid && heroVidControl) {
7+
// Remove native controls and show custom button
8+
heroVid.removeAttribute("controls");
9+
heroVidControl.removeAttribute("hidden");
10+
11+
// Media query for reduced motion preference
12+
var motionQuery = window.matchMedia("(prefers-reduced-motion)");
13+
14+
// Helper to update button text
15+
function updateButtonState(isPlaying) {
16+
const label = isPlaying ? heroVidControl.dataset.videoPause : heroVidControl.dataset.videoPlay;
17+
heroVidControl.querySelector("span").innerText = label;
18+
heroVidControl.classList.toggle("js-play-video", isPlaying);
19+
}
20+
21+
// Play video with error handling
22+
function playHeroVid() {
23+
heroVid.play().then(() => {
24+
updateButtonState(true);
25+
}).catch((error) => {
26+
console.warn("Video play failed:", error);
27+
updateButtonState(false);
28+
});
29+
}
30+
31+
// Pause video
32+
function pauseHeroVid() {
33+
heroVid.pause();
34+
updateButtonState(false);
35+
}
36+
37+
// Handle user motion preference
38+
function handleReduceMotionChanged() {
39+
if (motionQuery.matches) {
40+
pauseHeroVid();
41+
} else {
42+
playHeroVid();
43+
}
44+
}
45+
46+
// Attempt to autoplay
47+
var promise = heroVid.play();
48+
if (promise !== undefined) {
49+
promise
50+
.then(() => {
51+
updateButtonState(true);
52+
})
53+
.catch((error) => {
54+
console.warn("Autoplay was prevented:", error);
55+
updateButtonState(false);
56+
});
57+
}
58+
59+
// Media query listener
60+
motionQuery.addEventListener("change", handleReduceMotionChanged);
61+
handleReduceMotionChanged();
62+
63+
// Toggle video playback on control click
64+
document.addEventListener("click", function (event) {
65+
const button = event.target.closest('[data-video-control="hero"]');
66+
if (button) {
67+
if (heroVid.paused) {
68+
playHeroVid();
69+
} else {
70+
pauseHeroVid();
71+
}
72+
}
73+
});
74+
75+
// Unregister media query listener on page unload to prevent memory leaks
76+
window.addEventListener("beforeunload", () => {
77+
motionQuery.removeEventListener("change", handleReduceMotionChanged);
78+
});
79+
}
80+
}
81+
export {videoHero}

assets-src/styles/sass/50-core-components/_hero.scss

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,21 @@
5555
}
5656

5757
.hero .button {
58+
align-items: center;
5859
align-self: flex-start;
60+
display: inline-flex;
61+
justify-content: center;
62+
}
63+
64+
65+
.hero--video .sidebar__video {
66+
margin-inline: auto;
67+
max-inline-size: rem(500);
68+
position: relative;
69+
}
70+
71+
.hero--video video {
72+
display: block;
5973
}
6074

6175
.hero--listing {

assets-src/styles/sass/50-core-components/_navigation.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
align-items: center;
1717
display: flex;
1818
flex-wrap: wrap;
19+
gap: em(48);
1920

2021
@include mq($max-width) {
2122
flex-wrap: nowrap;

assets-src/styles/sass/60-advanced-components/_hero.scss

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,29 @@
66
h2 {
77
display: none;
88
}
9+
}
10+
11+
12+
13+
14+
.js .hero--video [data-video-control="hero"] {
15+
margin-block-start: 1rem;
16+
}
17+
18+
.js .hero--video [data-video-control="hero"] > * {
19+
pointer-events: none;
20+
}
21+
22+
.js .hero--video [data-video-control="hero"] .pause-icon {
23+
display: none;
24+
}
25+
26+
.js .hero--video [data-video-control="hero"].js-play-video {
27+
.pause-icon {
28+
display: block;
29+
}
30+
31+
.play-icon {
32+
display: none;
33+
}
934
}

design-system-templates/components/hero-home.html.twig

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<h2>Illustration Hero</h2>
12
<div class="u-full-width hero">
23
<div class="l-center">
34
<div class="l-sidebar">
@@ -14,3 +15,44 @@
1415
</div>
1516
</div>
1617
</div>
18+
19+
<h2>Video Hero</h2>
20+
<div class="u-full-width hero">
21+
<div class="l-center">
22+
<div class="l-sidebar">
23+
<div>
24+
<div class="not-sidebar">
25+
<h1>We believe in one web for all</h1>
26+
<p class="lead">We develop
27+
<a href="path/to/page">standards and guidelines</a>
28+
to help everyone build a web based on the principles of
29+
<a href="path/to/page">accessibility</a>,
30+
<a href="path/to/page">internationalization</a>,
31+
<a href="path/top/page">privacy</a>
32+
and
33+
<a href="path/top/page">security</a>.</p>
34+
<a href="path/to/page" class="button button--alt">Find out more about W3C</a>
35+
</div>
36+
<div class="sidebar">
37+
<div class="l-frame l-frame--16-9">
38+
<video controls loop muted playsinline preload="metadata" data-video="hero">
39+
<source src="https://videos.pexels.com/video-files/1481903/1481903-hd_1920_1080_25fps.mp4" type="video/mp4">
40+
Sorry, your browser does not support embedded videos. This is an animation of the W3C logo morphing into a new design.
41+
</video>
42+
</div>
43+
<button class="button button--ghost" data-video-control="hero" hidden>
44+
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 47 47" height="45" width="45" aria-hidden="true" focusable="false">
45+
<defs/>
46+
<g fill="none" fill-rule="evenodd">
47+
<path fill="#1E3773" fill-rule="nonzero" stroke="#FFF" stroke-opacity=".8" stroke-width="3.75" d="M23.914 2.818a21.222 21.222 0 0114.937 6.108c3.813 3.762 6.173 8.956 6.173 14.695 0 4.204-1.286 8.201-3.555 11.55a21.036 21.036 0 01-9.48 7.668 21.405 21.405 0 01-12.222 1.183 21.205 21.205 0 01-10.82-5.706 20.685 20.685 0 01-5.77-10.65 20.489 20.489 0 011.206-12.008 20.855 20.855 0 017.78-9.335 21.335 21.335 0 0111.751-3.505z" opacity=".8"/>
48+
<path class="play-icon" fill="#FFF" fill-rule="nonzero" d="M20.065 31.18l12.748-7.57-12.748-7.548z"/>
49+
<path class="pause-icon" fill="#FFF" d="M26.232 16.062h5v15h-5zM16.232 16.062h5v15h-5z"/>
50+
</g>
51+
</svg>
52+
<span class="visuallyhidden">Play</span>
53+
</button>
54+
</div>
55+
</div>
56+
</div>
57+
</div>
58+
</div>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
{% extends 'base.html.twig' %}
2+
3+
{% block title %}Landing with new logo template{% endblock %}
4+
{% block meta_description %}Landing page template from the W3C design system{% endblock %}
5+
6+
{% block body_class %}class="landing"{% endblock %}
7+
8+
{% block breadcrumbs %}
9+
{% include 'components/breadcrumbs.html.twig' %}
10+
{% endblock %}
11+
12+
{% block header %}
13+
{% include 'components/header-new-logo.html.twig' %}
14+
{% endblock %}
15+
16+
{% block content %}
17+
18+
{% include 'components/hero-landing.html.twig' %}
19+
20+
<div class="component component--columns component--columns--images">
21+
<h2>Section heading for these teasers</h2>
22+
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
23+
<ul class="clean-list" role="presentation">
24+
<li>
25+
{% include 'components/card-simple-image.html.twig' %}
26+
</li>
27+
<li>
28+
{% include 'components/card-simple-image.html.twig' %}
29+
</li>
30+
<li>
31+
{% include 'components/card-simple-image.html.twig' %}
32+
</li>
33+
<li>
34+
{% include 'components/card-simple-image.html.twig' %}
35+
</li>
36+
<li>
37+
{% include 'components/card-simple-image.html.twig' %}
38+
</li>
39+
<li>
40+
{% include 'components/card-simple-image.html.twig' %}
41+
</li>
42+
</ul>
43+
</div>
44+
45+
<div class="component component--columns component--columns--icons">
46+
<h2>Section heading for these teasers</h2>
47+
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
48+
<ul class="clean-list" role="presentation">
49+
<li>
50+
{% include 'components/card-simple-icon.html.twig' %}
51+
</li>
52+
<li>
53+
{% include 'components/card-simple-icon.html.twig' %}
54+
</li>
55+
<li>
56+
{% include 'components/card-simple-icon.html.twig' %}
57+
</li>
58+
<li>
59+
{% include 'components/card-simple-icon.html.twig' %}
60+
</li>
61+
<li>
62+
{% include 'components/card-simple-icon.html.twig' %}
63+
</li>
64+
<li>
65+
{% include 'components/card-simple-icon.html.twig' %}
66+
</li>
67+
<li>
68+
{% include 'components/card-simple-icon.html.twig' %}
69+
</li>
70+
</ul>
71+
</div>
72+
73+
{% include 'components/fifty-fifty.html.twig' %}
74+
75+
{% include 'components/fifty-fifty-reversed.html.twig' %}
76+
77+
{% include 'components/text.html.twig' %}
78+
79+
{% include 'components/image.html.twig' %}
80+
81+
{% include 'components/video.html.twig' %}
82+
83+
{% include 'components/quote.html.twig' %}
84+
85+
{% endblock %}
86+
87+
{% block crosslinks %}
88+
{% include 'components/crosslinks.html.twig' %}
89+
{% endblock %}
90+
91+
{% block scripts %}
92+
{% endblock %}

docs/components/navigation-v1.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Navigation with new logo
2+
3+
The following example shows how the global navigation sits within the [header component](header.md).
4+
5+
<example title="Header including main navigation" src="components/header-new-logo.html.twig" />
6+
7+
## Considerations
8+
9+
Note the use of the inline style `display: none;` on the button element with the data attribute `data-trigger="mobile-nav"`. This data attribute is targeted by the JavaScript for the global navigation. In the absence of JavaScript, which is required for the off-canvas mobile navigation, the button remains hidden to users.
10+
11+
The inline style `display: none;` is also used on instances of `.nav__submenu`. As the sub-navigation requires JavaScript for the drop-down effect, this keeps it hidden if JavaScript is not available. It also prevents the sub-menus from flashing from visible to hidden when an uncached page first loads.
12+
13+
If a top level navigation item will have child links, indicated by the `.has-children` class on the `<li>`, JavaScript replaces the link with a button for toggling the display of the sub-navigation.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Landing page with new logo
2+
3+
<example title="Landing with new logo v1" src="example-pages/new-logo-page.html.twig" standalone />

templates/components/styles/hero.html.twig

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="u-full-width hero">
1+
<div class="u-full-width hero {% if page.heroVideo is defined and page.heroVideo %}hero--video{% endif %}">
22
<div class="l-center">
33
<div class="l-sidebar">
44
<div>
@@ -11,7 +11,25 @@
1111
<p class="lead">{{ page.pageLead|raw }}</p>
1212
{% endblock %}
1313
</div>
14-
{% if page.heroIllustration is defined and page.heroIllustration %}
14+
{% if page.heroVideo is defined and page.heroVideo %}
15+
<div class="sidebar">
16+
<div class="sidebar__video">
17+
<div class="l-frame l-frame--16-9">
18+
<video controls loop muted playsinline preload="metadata" data-video="hero">
19+
<source src="{{ page.heroVideo[0].url }}" type="video/mp4">
20+
{{ 'components.hero.video.not_supported'|trans({video_url: page.heroVideo[0].url}, 'w3c_website_templates_bundle') }}
21+
</video>
22+
</div>
23+
<button class="button" hidden data-video-control="hero" data-video-play="{{ 'components.hero.video.play'|trans({}, 'w3c_website_templates_bundle') }}" data-video-pause="{{ 'components.hero.video.pause'|trans({}, 'w3c_website_templates_bundle') }}">
24+
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 640 640" height="20" width="20" aria-hidden="true" focusable="false">
25+
<!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
26+
<path class="play-icon" d="M187.2 100.9c-12.4-6.8-27.4-6.5-39.6.7-12.2 7.2-19.6 20.3-19.6 34.4v368c0 14.1 7.5 27.2 19.6 34.4 12.1 7.2 27.2 7.5 39.6.7l336-184c12.8-7 20.8-20.5 20.8-35.1 0-14.6-8-28.1-20.8-35.1l-336-184z"/>
27+
<path class=pause-icon d="M176 96c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h64c26.5 0 48-21.5 48-48V144c0-26.5-21.5-48-48-48h-64zm224 0c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h64c26.5 0 48-21.5 48-48V144c0-26.5-21.5-48-48-48h-64z"/></svg>
28+
<span class="visuallyhidden">{{ 'components.hero.video.play'|trans({}, 'w3c_website_templates_bundle') }}</span>
29+
</button>
30+
</div>
31+
</div>
32+
{% elseif page.heroIllustration is defined and page.heroIllustration %}
1533
<div class="sidebar">
1634
<img src="{{ page.heroIllustration.url }}" alt/>
1735
</div>

0 commit comments

Comments
 (0)