Skip to content

Ensure focused search input in header renders consistently across breakpoints #1317

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions backstop.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,17 @@ module.exports = {
viewports.get('large-desktop')
]
},
{
clickSelector: '.nhsuk-header__search-input',
label: 'Header with search (focused search input)',
url: `${BASE_URL}/components/header/header-search.html`,
viewports: [
viewports.get('mobile'),
viewports.get('tablet'),
viewports.get('desktop'),
viewports.get('large-desktop')
]
},
{
label: 'Header with account (logged in)',
url: `${BASE_URL}/components/header/header-account-logged-in.html`,
Expand Down Expand Up @@ -687,6 +698,18 @@ module.exports = {
viewports.get('large-desktop')
]
},
{
clickSelector: '.nhsuk-header__search-input',
label: 'Header organisational with white header (focused search input)',
url: `${BASE_URL}/components/header/header-org-white.html`,
onReadyScript: 'playwright/onReadyResize.js',
viewports: [
viewports.get('mobile'),
viewports.get('tablet'),
viewports.get('desktop'),
viewports.get('large-desktop')
]
},
{
label: 'Header organisational with white header, navigation',
url: `${BASE_URL}/components/header/header-org-white-nav.html`,
Expand Down
104 changes: 71 additions & 33 deletions packages/components/header/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
@use "../../core/settings" as *;
@use "../../core/tools" as *;

$_header-item-padding: 12px;

////
/// Header component
///
Expand Down Expand Up @@ -85,24 +87,44 @@
/// Account

.nhsuk-header__account {
background: nhsuk-shade($color_nhsuk-blue, 20%);
position: relative;
border-radius: $nhsuk-border-radius;
flex-grow: 1;
outline: 1px solid nhsuk-shade($color_nhsuk-blue, 20%);
margin-bottom: 1px;

@include nhsuk-media-query($from: tablet) {
align-self: start;
}

.nhsuk-icon__user {
height: 24px;
width: 24px;
flex-shrink: 0;
}

&,
&::before {
background-color: nhsuk-shade($color_nhsuk-blue, 20%);
}

// Expand header account by 1px to ensure the search
// input does not appear to be taller when inline
&::before {
content: "";
display: block;
position: absolute;
top: -1px;
right: 0;
bottom: -1px;
left: 0;
border: 1px solid nhsuk-shade($color_nhsuk-blue, 20%);
border-radius: $nhsuk-border-radius + 1px;
}
Comment on lines +106 to +118
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulrobertlloyd I've switched to ::before with a regular border here

Testing in older Safari showed that outline: 1px… didn't follow border-radius 😭

We also only need to offset the vertical height (making it appear taller, but not wider)


@include nhsuk-media-query($from: tablet) {
align-self: start;
}
}

.nhsuk-header__account-list {
position: relative;
z-index: 1;
display: flex;
flex-wrap: wrap;
gap: 1px;
Expand All @@ -113,14 +135,13 @@
}

.nhsuk-header__account-item {
background-color: nhsuk-shade($color_nhsuk-blue, 20%);
display: flex;
flex-grow: 1;
gap: nhsuk-spacing(2);
margin: 0;
outline: 1px solid $color_nhsuk-blue;
overflow-wrap: anywhere;
padding: nhsuk-spacing(2) 12px;
padding: nhsuk-spacing(2) $_header-item-padding;
@include nhsuk-font(16);

&:nth-last-child(2) {
Expand Down Expand Up @@ -159,47 +180,58 @@
flex-grow: 1;
position: relative;
z-index: 13;

@include nhsuk-print-hide;

.nhsuk-icon__search {
height: 28px;
width: 28px;

// Adjust optical alignment due to the handle appearing
// to push the magnifying glass circle to the top left
margin: 0 -2px -2px 0;
Comment on lines +190 to +192
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hope this is alright?

Although perfectly aligned, the magnifying glass seemed pushed into the top left

Similarly we had a 2px transparent border on the left which needed to be offset back to 12px

Adjustments

}
}

.nhsuk-header__search-form {
display: flex;
height: 100%;
overflow: visible;

@include nhsuk-media-query($until: tablet) {
position: relative;
}
}

.nhsuk-header__search-input {
border: 1px solid $color_nhsuk-white;
// 1. Disable default search input appearance
.nhsuk-header__search-input.nhsuk-input {
border-color: transparent;
border-radius: $nhsuk-border-radius 0 0 $nhsuk-border-radius;
font-size: $nhsuk-base-font-size;
height: 40px;
padding: 0 12px;
margin-right: -$nhsuk-border-width-form-element;
padding-right: $_header-item-padding;
padding-left: $_header-item-padding - $nhsuk-border-width-form-element;
Comment on lines +208 to +209
Copy link
Contributor

@colinrotherham colinrotherham May 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Right padding was good
    We've already used -2px margin to hide the 2px transparent border

  2. Left padding appeared 2px too wide (14px not 12px)
    For comparison see screenshot in comment above

width: 100%;
@include nhsuk-font-size(16);

&:focus {
border: nhsuk-spacing(1) solid $nhsuk-focus-text-color;
box-shadow: 0 0 0 $nhsuk-focus-width $nhsuk-focus-color;
outline: $nhsuk-focus-width solid transparent;
outline-offset: $nhsuk-focus-width;
padding: 0 9px;
z-index: 10;
}

&::placeholder {
color: $color_nhsuk-grey-1;
opacity: 1; // Fixes low contrast of placeholder text in firefox
}

// Hide search input clear button (IE)
&::-ms-clear {
display: none;
}

// Hide search input icon and cancel button (WebKit, Blink)
&::-webkit-search-decoration,
&::-webkit-search-cancel-button {
appearance: none;
}

Comment on lines +222 to +232
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When text is entered we should remove the "clear" icon

Although the icon wasn't visible by default, space was still reserved for it

@include nhsuk-media-query($until: tablet) {
border-radius: $nhsuk-border-radius;
font-size: inherit;
}
}

Expand All @@ -208,18 +240,12 @@
border: 0;
border-radius: 0 $nhsuk-border-radius $nhsuk-border-radius 0;
color: $color_nhsuk-blue;
flex-shrink: 0;
height: nhsuk-spacing(6);
line-height: 1;
outline: none;
margin: 0;
width: 44px;

@include nhsuk-media-query($until: tablet) {
position: absolute;
right: 0;
top: 0;
z-index: 9;
}
z-index: 9;

&:hover {
background-color: $color_shade_nhsuk-blue-35;
Expand All @@ -235,6 +261,7 @@
&:focus {
background-color: $nhsuk-focus-color;
box-shadow: inset 0 -4px 0 0 $nhsuk-focus-text-color;

@include nhsuk-focused-button;
}
}
Expand Down Expand Up @@ -447,20 +474,31 @@
}

.nhsuk-header__account,
.nhsuk-header__account-item {
.nhsuk-header__account::before {
background-color: $color_nhsuk-grey-5;
}

.nhsuk-header__account::before {
border-color: $color_nhsuk-grey-4;
}

.nhsuk-header__account-item {
outline-color: $color_nhsuk-grey-4;
}

.nhsuk-header__account-link {
@include nhsuk-link-style-no-visited-state;
}

.nhsuk-header__search-input {
.nhsuk-header__search-input.nhsuk-input {
border-color: $color_nhsuk-grey-3;
border-width: 1px;
margin-right: -1px;

&:focus {
border-color: $nhsuk-focus-text-color;
border-width: 2px;
margin-right: -2px;
}
}

Expand Down Expand Up @@ -513,7 +551,7 @@
}

.nhsuk-header__navigation-container {
border-top-color: $color_nhsuk-grey-5;
border-color: $color_nhsuk-grey-4;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulrobertlloyd On the blue nav this border colour has much stronger contrast

Are you happy if we do the same for the white one—picking the darker grey?

border-top-width: 1px;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/components/header/template.njk
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
<search class="nhsuk-header__search">
<form class="nhsuk-header__search-form" id="search" action="{{ searchAction }}" method="get">
<label class="nhsuk-u-visually-hidden" for="search-field">{{ searchVisuallyHiddenLabel }}</label>
<input class="nhsuk-header__search-input" id="search-field" name="{{ searchName }}" type="search" placeholder="{{ searchPlaceholder }}" autocomplete="off">
<input class="nhsuk-header__search-input nhsuk-input" id="search-field" name="{{ searchName }}" type="search" placeholder="{{ searchPlaceholder }}" autocomplete="off">
<button class="nhsuk-header__search-submit" type="submit">
<svg class="nhsuk-icon nhsuk-icon__search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M19.71 18.29l-4.11-4.1a7 7 0 1 0-1.41 1.41l4.1 4.11a1 1 0 0 0 1.42 0 1 1 0 0 0 0-1.42zM5 10a5 5 0 1 1 5 5 5 5 0 0 1-5-5z"></path>
Expand Down
Binary file modified tests/backstop/bitmaps_reference/Header_default_desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/backstop/bitmaps_reference/Header_default_mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/backstop/bitmaps_reference/Header_default_tablet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/backstop/bitmaps_reference/Header_organisational_mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Binary file modified tests/backstop/bitmaps_reference/Header_with_search_desktop.png
Binary file modified tests/backstop/bitmaps_reference/Header_with_search_mobile.png
Binary file modified tests/backstop/bitmaps_reference/Header_with_search_tablet.png