From 237235a3fcc063096dd343ca6b6cd5f5bbf1a7a1 Mon Sep 17 00:00:00 2001 From: Ian James Date: Tue, 14 Sep 2021 14:43:03 +0100 Subject: [PATCH] Add mixin for more robust navigation updates The mixin outputs the styles needed for the grid layout to work in IE10+ - this is quite a repetative syntax, so the mixin takes the number of items and the number of columns and works out the rest. Added comments to the pertinent parts of the navigation localisation to remind future people that they need to update the styles as well. --- .../_layout-super-navigation-header.scss | 230 ++++++++---------- config/locales/en.yml | 8 +- 2 files changed, 106 insertions(+), 132 deletions(-) diff --git a/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss b/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss index 06b2833f9c..1c141227c1 100644 --- a/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +++ b/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss @@ -1,3 +1,98 @@ +/// Set grid row or column value using the fraction unit. +/// +/// @param {Integer} $number - number of fractions that the grid row or column +/// needs to be divided into. +/// @returns {String} - the value +/// +/// @example scss - Five fractions will return `1fr 1fr 1fr 1fr 1fr`. +/// .container { +/// grid-template-rows: fractions(5); +/// } +/// +@function fractions($number) { + $fractions: '1fr'; + + @for $i from 1 to $number { + $fractions: $fractions + ' 1fr'; + } + + @return unquote($fractions); +} + + +/// Arrange items into vertical columns +/// +/// @param {Integer} $items - number of items that need to be arranged +/// @param {Integer} $columns - number of columns required +/// @param {String} $selector - (optional) the inner element to be targeted. +/// +/// @example scss - A 7 item 2 column layout. +/// .container { +/// @include columns(7, 2); +/// } + +/// @example scss - A 9 item 3 column layout that has `div`s as the inner +/// elements. +/// .container { +/// @include columns(9, 3, "div"); +/// } +/// +@mixin columns($items, $columns, $selector: "*") { + $rows: ceil($items / $columns); + + display: -ms-grid; + display: grid; + grid-auto-flow: column; + -ms-grid-columns: fractions($columns); + grid-template-columns: fractions($columns); + -ms-grid-rows: fractions($rows); + grid-template-rows: fractions($rows); + + // Internet Explorer 10-11 require each element to be placed in the grid - + // the `grid-auto-flow` property isn't supported. This means that both the + // column and row needs to be set for every element. + + // This creates a list of lists to represent the columns and rows; for + // example, a 7 item 2 column list would create this: + // [ + // [1, 2, 3, 4 ] // column one + // [5, 6, 7] // column two + // ] + $grid: (); + $counter: 0; + + @for $column from 1 through $columns { + $this-row: (); + + @for $row from 1 through $rows { + $counter: $counter + 1; + + @if $counter <= $items { + $this-row: append($this-row, $counter); + } + } + + $grid: append($grid, $this-row, "comma"); + } + + // Now we can loop through the list of lists to create the rules needed for + // the older grid syntax; fist looping through the list to get the number + // needed for the column, then looping again to get the number for the grid + // row: + @for $column_index from 1 through length($grid) { + $this-row: nth($grid, $column_index); + + @for $item-index from 1 through length($this-row) { + $this-item: nth($this-row, $item-index); + + & > #{$selector}:nth-child(#{$this-item}) { + -ms-grid-column: $column_index; + -ms-grid-row: $item-index; + } + } + } +} + $search-icon-size: 20px; @mixin chevron($colour) { @@ -579,11 +674,6 @@ $search-icon-size: 20px; padding: govuk-spacing(2) 0 govuk-spacing(6) 0; @include govuk-media-query($from: "desktop") { - display: -ms-grid; - display: grid; - grid-auto-flow: column; - -ms-grid-columns: 1fr 1fr; - grid-template-columns: 1fr 1fr; margin-left: (0 - govuk-spacing(3)); margin-right: (0 - govuk-spacing(3)); padding: govuk-spacing(6) 0 govuk-spacing(8) 0; @@ -597,136 +687,18 @@ $search-icon-size: 20px; } } -.gem-c-layout-super-navigation-header__navigation-second-items--government-activity { +.gem-c-layout-super-navigation-header__navigation-second-items--topics { @include govuk-media-query($from: "desktop") { - -ms-grid-rows: 1fr 1fr 1fr; - grid-template-rows: 1fr 1fr 1fr; - - & > li { - &:nth-child(1) { - -ms-grid-row: 1; - -ms-grid-column: 1; - } - - &:nth-child(2) { - -ms-grid-row: 2; - -ms-grid-column: 1; - } - - &:nth-child(3) { - -ms-grid-row: 3; - -ms-grid-column: 1; - } - - &:nth-child(4) { - -ms-grid-row: 1; - -ms-grid-column: 2; - } - - &:nth-child(5) { - -ms-grid-row: 2; - -ms-grid-column: 2; - } - } + // columns(number-of-items, number-of-columns) + @include columns(18, 2, "li"); } } -.gem-c-layout-super-navigation-header__navigation-second-items--topics { +.gem-c-layout-super-navigation-header__navigation-second-items--government-activity { @include govuk-media-query($from: "desktop") { - -ms-grid-rows: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr; - grid-template-rows: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr; - - & > li { - &:nth-child(1) { - -ms-grid-row: 1; - -ms-grid-column: 1; - } - - &:nth-child(2) { - -ms-grid-row: 2; - -ms-grid-column: 1; - } - - &:nth-child(3) { - -ms-grid-row: 3; - -ms-grid-column: 1; - } - - &:nth-child(4) { - -ms-grid-row: 4; - -ms-grid-column: 1; - } - - &:nth-child(5) { - -ms-grid-row: 5; - -ms-grid-column: 1; - } - - &:nth-child(6) { - -ms-grid-row: 6; - -ms-grid-column: 1; - } + padding-bottom: govuk-spacing(3); - &:nth-child(7) { - -ms-grid-row: 7; - -ms-grid-column: 1; - } - - &:nth-child(8) { - -ms-grid-row: 8; - -ms-grid-column: 1; - } - - &:nth-child(9) { - -ms-grid-row: 9; - -ms-grid-column: 1; - } - - &:nth-child(10) { - -ms-grid-row: 1; - -ms-grid-column: 2; - } - - &:nth-child(11) { - -ms-grid-row: 2; - -ms-grid-column: 2; - } - - &:nth-child(12) { - -ms-grid-row: 3; - -ms-grid-column: 2; - } - - &:nth-child(13) { - -ms-grid-row: 4; - -ms-grid-column: 2; - } - - &:nth-child(14) { - -ms-grid-row: 5; - -ms-grid-column: 2; - } - - &:nth-child(15) { - -ms-grid-row: 6; - -ms-grid-column: 2; - } - - &:nth-child(16) { - -ms-grid-row: 7; - -ms-grid-column: 2; - } - - &:nth-child(17) { - -ms-grid-row: 8; - -ms-grid-column: 2; - } - - &:nth-child(18) { - -ms-grid-row: 9; - -ms-grid-column: 2; - } - } + @include columns(5, 2, "li"); } } diff --git a/config/locales/en.yml b/config/locales/en.yml index 0bdeb13a34..e89b85b35c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -47,7 +47,7 @@ en: - We also use cookies set by other sites to help us deliver content from their services. title: Cookies on GOV.UK devolved_nations: - applies_to: Applies to + applies_to: Applies to england: England northern_ireland: Northern Ireland scotland: Scotland @@ -124,7 +124,8 @@ en: - label: Topics href: "/browse" description: Find information and services - menu_contents: + menu_contents: # If adding or removing items, remember to update the + # `columns` in the layout-super-navigation-header SCSS. - label: Benefits href: "/browse/benefits" - label: Births, death, marriages and care @@ -166,7 +167,8 @@ en: - label: Government activity href: "/search/news-and-communications" description: Find out what the government is doing - menu_contents: + menu_contents: # If adding or removing items, remember to update the + # `columns` in the layout-super-navigation-header SCSS. - label: News href: "/search/news-and-communications" description: News stories, speeches, letters and notices