All websites and all pages must include the header.
The header component is the first visible component on every page. The position of the header is fixed on the page.
Depending on the device’s screen resolution, the header switches to one of the two following modes:
The desktop header is used on desktop resolutions and tablets in landscape mode.
The desktop header can consist of four parts:
The top header with Ghent logo has the following components:
To get an idea of different combinations for the desktop header, how they look and how they work, see the examples.
Further specific requirements for the City of Ghent website and for separate websites are listed below.
The mobile header is used on tablet in portrait mode and below (mobile resolutions).
The mobile header can consist of three parts, from top to bottom:
The top header has the following components:
For the top header of the mobile header, the following conditions apply:
Where there is a header image, the header image in the mobile header can be shown or not shown. See the examples.
When the website has a search function, the search function is always shown in the header.
When the website has main navigation, the menu button is always shown in the header. The menu button opens the mobile menu with the main navigation.
When the website has main navigation and also the authentication component and/or a language switch, the authentication component and/or the language switch are integrated in the menu. In these cases, the menu button is always shown in the header. The menu button opens the mobile menu with the main navigation and the authentication component and/or the language switch. In other words: whenever the website has main navigation, the menu button is used and the authentication component and/or the language switch (if applicable) are integrated in the mobile menu.
When the website has no main navigation, but has a search function and the authentication component and a language switch, the menu button is used and the authentication component and the language switch are integrated in the menu. The search button is always shown in the header.
Taking the above conditions into account, only the following combinations of elements are possible in the top part of the mobile header:
To get an idea of different combinations for the mobile header, how they look and how they work, see the examples.
Further specific requirements for the City of Ghent website and for separate websites are listed below.
For websites that where users can authenticate themselves, the authentication component is included in the header.
The authentication component does not provide authentication itself but it is a way to make accessible authentication for the user and show the authentication status of the user.
The authentication mechanism can be anything from a magic link, to authentication using a user name and password, to strong authentication. The authentication mechanism that is used depends on the functional needs and requirements of the website itself.
For multilingual websites with synchronous translations, the language switch is included in the header. The language switch shows the current language and is a drop-down menu to let the user switch to another language. In the drop-down menu, the current language is shown first (as a label, not a link). After that, the other language in which the current page is available are shown. These other languages are shown as links that each link to the current page in those specific languages. See the examples.
The header can include a header image When included, the header image is always shown on desktop and tablet resolutions. The header image can have an optional caption tag. On mobile resolutions, the header image can be shown or not shown. This is a functional decision specific for the website or even for certain web pages within a website. The optional caption for the header image is never shown in the mobile header. See the examples.
{% set hasMenu = menu or (search and auth and translate) %}
<header class="header{{ hasMenu ? ' header--menu' : '' }}">
<div class="content-container">
{% include '@logo' with {
site_name: site_name,
type: subsite ? 'subsite' : ''
} %}
{% if search %}
{% include '@link' with {
link: "#",
text: "search",
modifier: "search--link",
title: "search"
} %}
{% include '@search' with {
label: header_search_label,
search_id: _self.name ~ '-header-search',
placeholder: header_search_placeholder,
modifier_search: header_search_modifier_search,
text: header_search_text,
modifier_submit: header_search_modifier_submit
} %}
{% endif %}
{% if auth %}
{% include '@authentication' with {
id: _self.name ~ '-authentication',
items: mijn_gent_block_items,
auth: mijn_gent_block_auth,
image: mijn_gent_block_image,
accordion: true
} %}
{% endif %}
{% if translate %}
{% include '@language-switcher' with {
accordion: true,
id: _self.name ~ '-translate'
} %}
{% endif %}
{% if hasMenu %}
{% set Auth %}
{% if auth %}
{% include '@authentication' with {
id: _self.name ~ '-authentication-mobile',
items: mijn_gent_block_items,
auth: mijn_gent_block_auth,
image: mijn_gent_block_image,
accordion: false
} %}
{% endif %}
{% endset %}
{% set Translate %}
{% if translate %}
{% include '@language-switcher' with {
accordion: false,
id: _self.name ~ '-translate-mobile'
} %}
{% endif %}
{% endset %}
{% include '@main-menu' with {
items: menu_items,
auth: Auth,
translate: Translate,
id: _self.name ~ '-menu',
} %}
{% endif %}
</div>
{% if subsite %}
<div class="site-name">
<span>{{ site_name }}</span>
</div>
{% endif %}
{% include '@breadcrumbs' with {
items: breadcrumbs_items,
id: _self.name ~ '-header-crumbs'
} %}
<hr/>
{% if hero_image_src %}
<figure class="hero{{ mobile_hero ? ' hero--mobile' : '' }}">
{% if theme %}
<div class="theme{{ theme_light ? ' theme--light' : '' }}">
<div class="theme-title">
{% include '@image' with {
'src': (theme_light ? figure_logo_src_dark : figure_logo_src_light) | path,
'alt_text': figure_logo_alt_text,
'modifier': null,
'ratio': null
} %}
{% if theme_title %}
{% include '@heading' with {
'type': 'h1',
'heading_text': hero_title
} %}
{% endif %}
</div>
</div>
{% endif %}
{% include '@image' with {
'src': hero_image_src,
'alt_text': '',
'ratio': '4:1'
} %}
{% if hero_image_description %}
{% include '@figcaption' with {
'figcaption': hero_image_description
} %}
{% endif %}
</figure>
{% endif %}
</header>
<header class="header">
<div class="content-container">
<a href="#" title="Home" class="site-logo " rel="home">
Stad Gent
</a>
<a href='#' class="search--link" title="search">
search </a>
<form class="form search">
<label for="hero_auth-header-search">Search
</label>
<input type="search" id="hero_auth-header-search" name="hero_auth-header-search" class="search" placeholder="Search" required="true" />
<input type="submit" value="Search" class="" />
</form>
<div class="authentication accordion">
<button aria-expanded="false" aria-controls="hero_auth-authentication" class="toggle accordion--button">
<span class="avatar">j</span>
<span>Webteam1_VOORNAAM DG_ACHTERNAAM</span>
</button>
<div id="hero_auth-authentication" class="accordion--content" aria-hidden="true" hidden>
<article class="content">
<h2>Mijn bibliotheek</h2>
<section class="profile">
<span class="avatar">j</span>
<div class="profile-info">
<span>Webteam1_VOORNAAM DG_ACHTERNAAM</span>
<a href='#' class="button button-primary button-small">
Show profile </a>
</div>
</section>
<section>
<ul class="links">
<li><a href='javascript:(void);'>Overzicht</a></li>
<li><a href='javascript:(void);'>Leestips</a></li>
</ul>
</section>
<section>
<h2>Mijn gent</h2>
<ul class="links">
<li><a href='javascript:(void);'>Mijn profiel</a></li>
<li><a href='javascript:(void);'>Nieuwsbrieven</a></li>
<li><a href='javascript:(void);'>Historiek</a></li>
</ul>
</section>
<footer>
<a href='javascript:(void);' class="button button-small button-secondary">
Afmelden </a>
</footer>
</article>
</div>
</div>
</div>
<nav class="breadcrumb section--default" aria-labelledby="hero_auth-header-crumbs">
<div class="content-container">
<h2 id="hero_auth-header-crumbs" class="visually-hidden">Breadcrumb</h2>
<ol class="no-style">
<li><a href='#'>Home</a></li>
<li><a href='#'>Society, Welfare & health</a></li>
<li><a href='#'>News & Events</a></li>
<li><span>Page title</span></li>
</ol>
</div>
</nav>
<hr />
<figure class="hero">
<figure>
<div class="image-wrapper" data-ratio="4:1"><img src="https://via.placeholder.com/1600x400&text=4:1+(1600x400)" alt="" /></div>
</figure>
<figcaption>Caption text comes here.</figcaption>
</figure>
</header>
{
"mijn_gent_block_items": [
"<a href='javascript:(void);'>Mijn profiel</a>",
"<a href='javascript:(void);'>Nieuwsbrieven</a>",
"<a href='javascript:(void);'>Historiek</a>"
],
"auth": true,
"search": true,
"translate": false,
"mijn_gent_block_auth": true,
"header_search_id": "header-search",
"header_search_label": "Search",
"header_search_placeholder": "Search",
"header_search_text": "Search",
"breadcrumbs_id": "system-breadcrumb",
"breadcrumbs_items": [
"<a href='#'>Home</a>",
"<a href='#'>Society, Welfare & health</a>",
"<a href='#'>News & Events</a>",
"<span>Page title</span>"
],
"hero_image_src": "https://via.placeholder.com/1600x400&text=4:1+(1600x400)",
"hero_image_description": "Caption text comes here.",
"hero_title": "ICT Supplier <span>District 09</span>",
"figure_logo_src_dark": "/styleguide/img/stock/district09-dark.svg",
"figure_logo_src_light": "/styleguide/img/stock/district09-light.svg",
"site_name": "Stad Gent",
"menu_items": [],
"mijn_gent_block_image": false
}
@use "sass:math";
header.header {
position: relative;
margin-bottom: .3rem;
padding: .3rem 0;
// first row
> .content-container {
display: flex;
align-items: center;
@include tablet {
flex-wrap: wrap;
}
> :not(:first-child) {
margin-left: gutter();
}
.site-logo {
margin-right: auto;
&.subsite {
flex: 1;
}
}
.search {
display: none;
flex: 1;
flex-wrap: nowrap;
justify-content: flex-end;
label {
@extend %visually-hidden;
@include bold-text;
}
input {
margin-bottom: 0;
}
input[type=submit] {
max-width: 0;
padding: 0;
transition: opacity .2s ease-in-out, max-width .2s ease-in-out, padding .2s ease-in-out;
box-shadow: none;
opacity: 0;
&:focus {
max-width: 9999px;
margin-left: .4rem;
padding: 0 1rem;
opacity: 1;
}
}
input[type=search],
input[type=text] {
flex: 0 1 auto;
width: 100%;
min-width: 0;
max-width: 210px;
margin-right: 0;
transition: max-width .2s ease-in-out;
&:invalid {
box-shadow: none;
}
&:focus,
&:valid {
max-width: 440px;
margin: 0 0 0 .4rem;
~ input[type=submit] {
max-width: 9999px;
margin-left: .4rem;
padding: 0 1rem;
opacity: 1;
}
}
}
@include tablet {
display: flex;
}
}
.search--link {
@include theme('background-color', 'color-primary--lighten-5', 'header-search-background-color');
display: block;
min-width: 2.4rem;
max-width: calc(.8rem + 32px);
height: 2.4rem;
border-bottom: 0;
border-radius: border-radius('radius-1');
background: svg-as-background('search', color('dark-gray'), 32, 32) no-repeat left .4rem center;
text-indent: -9999px;
overflow: hidden;
@include tablet {
display: none;
}
}
.authentication {
align-items: center;
margin-left: .8rem;
@include tablet {
margin-left: gutter();
}
}
.authentication,
.language-switcher {
align-self: stretch;
}
// Align main menu with site logo and breadcrumb.
nav.menu {
@include tablet {
flex-basis: 100%;
flex-grow: 1;
order: 9999;
margin-left: 0;
}
line-height: 1;
}
}
.site-name {
@include theme('color', 'color-tertiary', 'default-text-color');
@include bold-text;
@include tablet {
display: none;
}
margin: .8rem 0 .4rem;
font-size: .9rem;
}
nav.breadcrumb {
margin-top: .4rem;
}
hr {
$span: percentage(math.div(2, 12));
position: relative;
max-width: $bp-max-content;
margin-top: .3rem;
margin-bottom: 2.3rem;
border: 0;
overflow: visible;
&::before,
&::after {
@include theme('border-color', 'color-primary--lighten-4', 'header-border-bottom');
position: absolute;
top: 100%;
width: 100%;
height: 1rem;
margin-top: .3rem;
border-top: 2px solid;
content: '';
}
&::before {
left: -$gutter-width;
width: 3rem + $gutter-width;
border-right: 2px solid;
border-top-right-radius: border-radius('radius-4');
@include desktop {
left: 0;
width: calc(#{$span} + 2rem);
}
}
&::after {
right: -$gutter-width;
width: calc(100% - 3rem + 2px + #{$gutter-width});
border-left: 2px solid;
border-top-left-radius: border-radius('radius-4');
@include desktop {
right: 0;
width: calc(100% - #{$span} - 2rem + 2px);
}
}
}
// Hero image, overlaps and hides breadcrumb accolade.
figure.hero {
$span: percentage(math.div(2, 12));
display: none;
position: relative;
min-height: 1.6rem;
// Give the image 1px margin relative to the container
// so the accolade can overlap the edges
// IE error fix
margin: -1.7rem calc(-1rem + 1px) .3rem;
@include tablet {
display: block;
}
&.hero--mobile {
display: block;
&::before,
&::after {
content: '';
}
.image-wrapper,
img {
display: block;
}
}
.theme {
display: none;
position: absolute;
top: 0;
right: 0;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
margin: 0;
padding: $gutter-width 2rem;
text-align: center;
z-index: z('hero', 'base');
@include tablet {
display: flex;
width: span(4 wide of 12);
max-width: 23rem;
height: calc(100% - 1.6rem + 1px); // 1px to fix rendering issues
}
@include desktop {
padding: 0 2rem;
}
@media (min-width: $bp-max-content) {
right: calc((100% - #{$bp-max-content}) / 2);
}
&::before,
&::after {
@include theme('background-color', 'color-primary', 'hero-background-color');
@include theme('border-color', 'color-primary', 'hero-background-color');
position: absolute;
left: 0;
width: 100%;
height: auto;
border: 1px solid;
content: '';
opacity: .94;
z-index: z('hero', 'overlay');
}
&.theme--light {
&::before,
&::after {
@include theme('background-color', 'color-primary--lighten-5', 'hero-background-light-color');
@include theme('border-color', 'color-primary--lighten-5', 'hero-background-light-color');
opacity: 1;
}
h1 {
@include theme('color', 'color-tertiary', 'hero-light-text-color');
}
}
&::before {
top: 0;
bottom: 50%;
border-bottom-left-radius: border-radius('radius-5');
}
&::after {
top: 50%;
bottom: 0;
border-top-left-radius: border-radius('radius-5');
}
.theme-title {
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
min-height: 100%;
}
img {
display: inline-block;
width: auto;
height: 3rem;
margin-bottom: 1rem;
@include desktop {
height: 4rem;
}
@media (min-width: $bp-max-content) {
height: 5rem;
}
}
figure:last-child {
display: flex;
flex: .6 1 auto;
flex-direction: column;
img {
flex: 1 1 auto;
margin-bottom: 0;
}
}
h1 {
@include theme('color', 'color-secondary', 'hero-text-color');
margin: 0;
font-size: 1.2rem;
@include desktop {
font-size: 1.6rem;
}
@media (min-width: $bp-max-content) {
font-size: 2rem;
}
span {
display: block;
font-size: .9rem;
@include desktop {
font-size: 1.2rem;
}
@media (min-width: $bp-max-content) {
font-size: 1.5rem;
}
}
}
}
.image-wrapper {
display: none;
@include tablet {
display: block;
}
}
img {
display: none;
@include tablet {
display: block;
}
}
figcaption {
@extend %content-container;
display: none;
right: 0;
width: auto;
@include tablet {
display: block;
position: absolute;
top: calc(100% - 1.6rem);
left: 3rem + $gutter-width;
margin: 0;
padding: .4rem $gutter-width 0;
z-index: z('hero', 'caption');
}
@include desktop {
left: calc(#{$span} + 2rem);
}
@media (min-width: $bp-max-content) {
right: calc((100% - #{$bp-max-content}) / 2);
left: calc(#{$span} + 2rem + (100% - #{$bp-max-content}) / 2);
padding-right: 0;
}
}
&::before,
&::after {
position: absolute;
bottom: -.1rem;
height: 1rem;
background-color: color('white');
content: none;
z-index: z('hero', 'accolade');
@include tablet {
height: 1.7rem;
content: '';
}
}
&::before {
left: 0;
width: 4rem;
border-top-right-radius: border-radius('radius-3');
@include tablet {
width: 3rem + $gutter-width;
border-top-right-radius: border-radius('radius-5');
}
@include desktop {
width: calc(#{$span} + 2rem);
}
@media (min-width: $bp-max-content) {
width: calc(#{$span} + 2rem + ((100% - #{$bp-max-content}) / 2));
}
}
&::after {
right: 0;
left: 4rem;
width: auto;
border-top-left-radius: border-radius('radius-3');
@include tablet {
left: 3rem + $gutter-width;
border-top-left-radius: border-radius('radius-5');
}
@include desktop {
left: calc(#{$span} + 2rem);
}
@media (min-width: $bp-max-content) {
// Make sure it overlaps the image edges.
// IE error fix
right: -1px;
left: calc(#{$span} + 2rem + ((100% - #{$bp-max-content}) / 2));
}
}
&:not(.hero--subsite) .theme ~ figcaption {
left: 0;
width: 100%;
max-width: none;
background-color: color('white');
@media (min-width: $bp-max-content) {
width: auto;
}
}
&--subsite {
&::before,
&::after {
width: 100%;
}
}
}
&--menu > .content-container {
> .authentication,
> .language-switcher {
@include tablet-and-below {
display: none;
}
}
}
}