Header
On this page
Examples
Standalone
<header class="cads-header">
<div class="cads-grid-container">
<div class="cads-grid-row">
<nav class="cads-skip-links">
<a class="cads-skip-links__link" href="#cads-navigation">Skip to navigation</a>
<a class="cads-skip-links__link" href="#cads-main-content">Skip to main content</a>
<a class="cads-skip-links__link" href="#cads-footer">Skip to footer</a>
</nav>
<div class="cads-grid-col-md-2 cads-header__logo-row">
<a title="Citizens Advice homepage" class="cads-logo" href="/"></a>
<button
class="cads-header__search-reveal js-cads-search-reveal"
type="button"
aria-label="Open search"
aria-expanded="false"
aria-controls="header-search-form"
data-testid="expand-button"
data-descriptive-label-show="Open search"
data-descriptive-label-hide="Close search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="cads-icon cads-icon--small cads-icon--search" focusable="false" aria-hidden="true">
<path d="M13.842 12.294 11.514 9.86a5.162 5.162 0 0 0-.74-6.354A5.139 5.139 0 0 0 2 7.145a5.146 5.146 0 0 0 2.712 4.542 5.135 5.135 0 0 0 5.282-.257l2.304 2.413a.53.53 0 0 0 .751 0l.795-.796a.529.529 0 0 0-.002-.753Zm-6.703-2.223a2.925 2.925 0 0 1-2.87-2.358 2.93 2.93 0 0 1 1.75-3.277 2.925 2.925 0 0 1 3.554 1.079 2.93 2.93 0 0 1-.364 3.698 2.908 2.908 0 0 1-2.07.862v-.004Z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="cads-icon cads-icon--small cads-icon--close" focusable="false" aria-hidden="true">
<path d="M12.854 12.073a.5.5 0 0 0 0-.707L9.488 8l3.366-3.366a.5.5 0 0 0 0-.707l-.781-.78a.5.5 0 0 0-.707 0L8 6.511 4.634 3.146a.5.5 0 0 0-.707 0l-.78.781a.5.5 0 0 0 0 .707L6.511 8l-3.366 3.366a.5.5 0 0 0 0 .707l.781.78a.5.5 0 0 0 .707 0L8 9.489l3.366 3.366a.5.5 0 0 0 .707 0l.78-.781Z" />
</svg>
</button>
</div>
<div class="cads-grid-col-md-10 cads-header__search-row">
<ul class="cads-header__links js-cads-copy-into-nav">
<li class="cads-header__links-item"><span class="cads-header__text">Public site</span></li>
<li class="cads-header__links-item"><a class="cads-header__hyperlink" href="#">AdviserNet</a></li>
<li class="cads-header__links-item"><a class="cads-header__hyperlink" href="#">Intranet</a></li>
<li class="cads-header__links-item"><a class="cads-header__hyperlink" lang="cy" href="#">Cymraeg</a></li>
<li class="cads-header__links-item">
<div class="cads-header__account-link"><a data-testid="account-link" href="/sign-in">Sign in</a></div>
</li>
</ul>
<div class="cads-header__search-form" id="header-search-form">
<form role="search" class="cads-search cads-search--icon-only" action="/search" accept-charset="UTF-8" method="get"><input name="utf8" type="hidden" value="✓" autocomplete="off" />
<input type="search" name="q" id="search-query" aria-label="Search through site content" class="cads-search__input cads-input" autocomplete="off" />
<button
type="submit"
title="Submit search query"
data-testid="search-button"
class="cads-search__button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="cads-icon cads-icon--small cads-icon--search" focusable="false" aria-hidden="true">
<path d="M13.842 12.294 11.514 9.86a5.162 5.162 0 0 0-.74-6.354A5.139 5.139 0 0 0 2 7.145a5.146 5.146 0 0 0 2.712 4.542 5.135 5.135 0 0 0 5.282-.257l2.304 2.413a.53.53 0 0 0 .751 0l.795-.796a.529.529 0 0 0-.002-.753Zm-6.703-2.223a2.925 2.925 0 0 1-2.87-2.358 2.93 2.93 0 0 1 1.75-3.277 2.925 2.925 0 0 1 3.554 1.079 2.93 2.93 0 0 1-.364 3.698 2.908 2.908 0 0 1-2.07.862v-.004Z" />
</svg>
<span class="cads-search__button-label">Search</span>
</button>
</form>
</div>
</div>
</div>
</div>
</header>
<%= render CitizensAdviceComponents::Header.new do |c|
c.with_logo(title: "Citizens Advice homepage", url: "/")
c.with_skip_links([
{ title: "Skip to navigation", url: "#cads-navigation" },
{ title: "Skip to main content", url: "#cads-main-content" },
{ title: "Skip to footer", url: "#cads-footer" }
])
c.with_header_links([
{ title: "Public site", url: "#", current_site: true },
{ title: "AdviserNet", url: "#" },
{ title: "Intranet", url: "#" },
{ title: "Cymraeg", url: "#", lang: "cy" },
])
c.with_search_form(search_action_url: "/search")
c.with_account_link(title: "Sign in", url: "/sign-in")
end %>
With navigation
The header is intended to be used alongside the navigation, although it works standalone, see the navigation component docs for details on how to use the navigation component.
JavaScript behaviour
If you plan to use this component you will need to initialise the following JavaScript:
import { initHeader } from '@citizensadvice/design-system';
initHeader();
Using with Rails
If you are using the citizens_advice_components
gem, you can call the component from within a template using:
<%= render CitizensAdviceComponents::Header.new do |c|
c.with_logo(title: "Citizens Advice homepage", url: "/")
c.with_skip_links([
{ title: "Skip to navigation", url: "#cads-navigation" },
{ title: "Skip to main content", url: "#cads-main-content" },
{ title: "Skip to footer", url: "#cads-footer" }
])
c.with_header_links([
{ title: "Public site", url: "#", current_site: true },
{ title: "AdviserNet", url: "#" },
{ title: "Intranet", url: "#" },
{ title: "Cymraeg", url: "#", lang: "cy" },
])
c.with_search_form(search_action_url: "/search")
c.with_account_link(title: "Sign in", url: "/sign-in")
end %>
Slots API
The header component makes heavy use of view component slots. This allows each piece of the header to be configure each part of the header with a method.
Slots that have plural names like skip_links
and header_links
can be configured in flexible ways. Either by passing an array to the plural version of the method:
<%= render CitizensAdviceComponents::Header.new do |c|
c.with_header_links([{ title: "Example link", url: "/some-url" }])
end %>
Or by calling the singular method name multiple times:
<%= render CitizensAdviceComponents::Header.new do |c|
c.with_header_link(title: "Example link 1", url: "/some-url")
c.with_header_link(title: "Example link 2", url: "/another-url")
end %>
Logo slot
This is the only slot required by default. The logo slot can be configured in two different ways. Either as a plain link accepting a title
and an optional url
(defaults to /
):
<%= render CitizensAdviceComponents::Header.new do |c|
c.with_logo(title: "Citizens Advice homepage", url: "/")
end %>
Or by passing a custom block to render your own HTML:
<%= render CitizensAdviceComponents::Header.new do |c| %>
<% c.with_logo do %>
<a href="/" aria-label="AdviserNet" class="custom-logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 239 52">
<path d="M49 24.394C49 39.466 36.17 52 23.009 52c0 0 1.513-4.003 1.491-4.003-13.528 0-24.5-9.991-24.5-23.576C0 10.934 10.97.001 24.5.001S49 10.933 49 24.42M77.859 38l-1.656-5.438h-8.328L66.218 38H61l8.062-22.938h5.922L83.078 38h-5.219zm-2.813-9.5a4552.412 4552.412 0 01-2.593-8.36 26.25 26.25 0 01-.407-1.53c-.343 1.333-1.328 4.63-2.953 9.89h5.953zm16.078 9.813c-2.052 0-3.666-.797-4.843-2.391-1.167-1.594-1.75-3.802-1.75-6.625 0-2.865.593-5.094 1.781-6.688 1.198-1.604 2.844-2.406 4.938-2.406 2.197 0 3.874.854 5.03 2.563h.157c-.24-1.302-.36-2.464-.36-3.485v-5.594h4.781V38h-3.655l-.922-2.266h-.203c-1.084 1.719-2.735 2.578-4.953 2.578zm1.672-3.797c1.22 0 2.11-.354 2.672-1.063.573-.708.886-1.911.938-3.61v-.515c0-1.875-.292-3.219-.875-4.031-.573-.813-1.51-1.219-2.813-1.219-1.062 0-1.89.453-2.484 1.36-.584.895-.875 2.203-.875 3.921 0 1.72.297 3.01.89 3.875.594.854 1.443 1.282 2.547 1.282zM110 38l-6.656-17.469h4.984l3.375 9.953c.375 1.26.61 2.453.703 3.578h.094c.052-1 .286-2.192.703-3.578l3.36-9.953h4.984L114.89 38H110zm13.86-21.984c0-1.552.864-2.328 2.593-2.328s2.594.776 2.594 2.328c0 .74-.219 1.318-.656 1.734-.427.407-1.073.61-1.938.61-1.729 0-2.594-.781-2.594-2.344zM128.826 38h-4.766V20.531h4.766V38zm17.203-5.188c0 1.792-.625 3.157-1.875 4.094-1.239.938-3.099 1.406-5.578 1.406-1.27 0-2.354-.088-3.25-.265a11.985 11.985 0 01-2.516-.75v-3.938a16.65 16.65 0 002.985 1.047c1.114.281 2.094.422 2.937.422 1.73 0 2.594-.5 2.594-1.5 0-.375-.114-.677-.344-.906-.229-.24-.625-.505-1.187-.797a27.87 27.87 0 00-2.25-1.047c-1.344-.562-2.333-1.083-2.969-1.562-.625-.48-1.083-1.026-1.375-1.641-.28-.625-.422-1.39-.422-2.297 0-1.552.6-2.75 1.797-3.594 1.208-.854 2.917-1.28 5.125-1.28 2.104 0 4.151.457 6.141 1.374l-1.438 3.438a26.354 26.354 0 00-2.453-.922 7.698 7.698 0 00-2.328-.36c-1.406 0-2.109.38-2.109 1.141 0 .427.224.797.672 1.11.458.312 1.453.775 2.984 1.39 1.364.552 2.364 1.068 3 1.547.635.479 1.104 1.031 1.406 1.656s.453 1.37.453 2.234zm10.953-9.218c-1.01 0-1.802.323-2.375.969-.573.635-.9 1.541-.984 2.718h6.687c-.02-1.177-.328-2.083-.92-2.719-.595-.645-1.397-.968-2.408-.968zm.672 14.719c-2.812 0-5.01-.776-6.594-2.328-1.583-1.552-2.374-3.75-2.374-6.594 0-2.927.73-5.188 2.187-6.781 1.47-1.604 3.495-2.407 6.078-2.407 2.47 0 4.391.704 5.766 2.11s2.062 3.349 2.062 5.828v2.312h-11.265c.052 1.355.453 2.412 1.203 3.172s1.802 1.14 3.156 1.14a13.1 13.1 0 002.984-.327c.938-.219 1.917-.568 2.938-1.047v3.687c-.833.417-1.724.724-2.672.922-.948.209-2.104.313-3.469.313zm20.75-18.11c.646 0 1.183.048 1.61.142l-.36 4.468c-.385-.104-.854-.156-1.406-.156-1.52 0-2.708.39-3.562 1.172-.844.781-1.266 1.875-1.266 3.281V38h-4.766V20.533h3.61l.703 2.937h.234a6.526 6.526 0 012.188-2.36 5.415 5.415 0 013.015-.905zm25.422 17.798h-6.156l-9.938-17.281h-.14c.198 3.052.297 5.229.297 6.531v10.75h-4.329V15.157h6.11l9.922 17.109h.11c-.157-2.969-.235-5.068-.235-6.297V15.156h4.36v22.845zm12.625-14.406c-1.01 0-1.802.323-2.375.969-.573.635-.9 1.541-.984 2.718h6.687c-.02-1.177-.328-2.083-.922-2.719-.593-.645-1.395-.968-2.406-.968zm.672 14.719c-2.813 0-5.01-.776-6.594-2.328-1.583-1.552-2.375-3.75-2.375-6.594 0-2.927.73-5.188 2.188-6.781 1.468-1.604 3.495-2.407 6.078-2.407 2.47 0 4.39.703 5.766 2.11 1.374 1.406 2.062 3.349 2.062 5.828v2.312h-11.266c.052 1.355.454 2.412 1.204 3.172s1.802 1.14 3.156 1.14a13.1 13.1 0 002.984-.327c.938-.219 1.917-.568 2.938-1.047v3.687a10.95 10.95 0 01-2.672.922c-.948.209-2.104.313-3.469.313zm18.36-3.797c.833 0 1.833-.182 3-.547v3.547c-1.188.531-2.646.797-4.376.797-1.906 0-3.297-.48-4.17-1.438-.866-.968-1.298-2.416-1.298-4.343V24.11h-2.282v-2.016l2.625-1.594 1.375-3.687h3.047v3.719h4.891v3.578h-4.89v8.421c0 .678.187 1.178.562 1.5.385.324.89.485 1.515.485z"/>
</svg>
</a>
<% end %>
<% end %>
Skip links
Skip links are optional. We provide a default set for you but you can provide your own.
<%= render CitizensAdviceComponents::Header.new do |c|
c.with_skip_links([
{ title: "Skip to content", url: "#content" },
{ title: "Skip to footer", url: "#footer" }
])
end %>
If you use the defaults you’ll need to be using the Navigation
and Footer
components and add a #cads-main-content
ID to your main content area.
Header links
Header links can be configured either by passing a list of hashes to header_links
or by calling header_links
multiple times with a title
and url
. There is also an optional lang
attribute available. Header links also accept an optional current_site
flag, which turns the link into a span
.
<%= render CitizensAdviceComponents::Header.new do |c|
c.with_header_links([
{ title: "Public site", url: "/", current_site: true },
{ title: "AdviserNet", url: "/advisernet" },
{ title: "Cymraeg", url: "?lang=cy", lang: "cy" }
])
end %>
Search form slot
The search form is optional. In order to configure it you need to provide a search_action_url
and optionally a search_param
name (defaults to :q
).
<%= render CitizensAdviceComponents::Header.new do |c|
c.with_search_form(search_action_url: "/search", search_param: :search)
end %>
Account link slot
The account link slot can be configured in two different ways. Either as a plain link accepting a title
and url
:
<%= render CitizensAdviceComponents::Header.new do |c|
c.with_account_link(title: "Sign in", url: "/sign-in")
end %>
Or by passing a custom block to render your own HTML:
<%= render CitizensAdviceComponents::Header.new do |c| %>
<% c.with_account_link do %>
<%= form_tag("/sign-out", class: "cads-header__account-form", authenticity_token: false) do %>
<%= button_tag("Sign out", class: %w[cads-button__tertiary cads-header__sign-out js-cads-close-on-blur]) %>
<% end %>
<% end %>
<% end %>
Note: If you use the custom block format you control the HTML rendered so you’ll also need to handle styling yourself.
However, there are some basic form
and button
styles you can use to render a simple ‘Sign out’ button included in the design-system styles and shown in the example above.
Questions and contributions
All design system discussions take place in the #design-system Slack channel. For current issues, roadmap and other info see the Github project board and related issues.