From a5b3b4f6654fb5895d70ce17222294b27fdb44e8 Mon Sep 17 00:00:00 2001 From: Mason Hu Date: Thu, 28 Mar 2024 10:50:06 +0200 Subject: [PATCH] feat: equal height grid row pattern - Added equal height grid row pattern with full screen sized dividers Signed-off-by: Mason Hu --- releases.yml | 4 + scss/_patterns_equal-height-row.scss | 190 ++++++++++++++++++ scss/_vanilla.scss | 24 ++- .../standalone/patterns_equal-height-row.scss | 11 + side-navigation.yaml | 2 + .../patterns/equal-height-row/25-75-grid.html | 106 ++++++++++ .../equal-height-row/4-items-per-column.html | 145 +++++++++++++ .../patterns/equal-height-row/default.html | 53 +++++ .../full-screen-dividers.html | 70 +++++++ templates/docs/patterns/equal-height-row.md | 99 +++++++++ 10 files changed, 693 insertions(+), 11 deletions(-) create mode 100644 scss/_patterns_equal-height-row.scss create mode 100644 scss/standalone/patterns_equal-height-row.scss create mode 100644 templates/docs/examples/patterns/equal-height-row/25-75-grid.html create mode 100644 templates/docs/examples/patterns/equal-height-row/4-items-per-column.html create mode 100644 templates/docs/examples/patterns/equal-height-row/default.html create mode 100644 templates/docs/examples/patterns/equal-height-row/full-screen-dividers.html create mode 100644 templates/docs/patterns/equal-height-row.md diff --git a/releases.yml b/releases.yml index 2aed374645..9ea75dec50 100644 --- a/releases.yml +++ b/releases.yml @@ -4,6 +4,10 @@ url: /docs/patterns/navigation status: Updated notes: We've updated the navigation to support new theming. + - component: Equal height row + url: /docs/patterns/equal-height-row + status: New + notes: We've introduced new equal height row component (.p-equal-height-row) to better align content across columns. - version: 4.9.0 features: - component: Images diff --git a/scss/_patterns_equal-height-row.scss b/scss/_patterns_equal-height-row.scss new file mode 100644 index 0000000000..84d6e906f9 --- /dev/null +++ b/scss/_patterns_equal-height-row.scss @@ -0,0 +1,190 @@ +@import 'settings'; + +// wrapper mixin that provides relevant class selectors for 1st, 2nd and 3rd dividers +@mixin position-divider-by-order-in-grid($divider-order, $large-screen: false) { + // for large screens, dividers are positioned as pseudo elements at row level + @if $large-screen { + @if $divider-order == 1 { + &.has-1st-divider::before { + @content; + } + } + + @if $divider-order == 2 { + &.has-2nd-divider::after { + @content; + } + } + + @if $divider-order == 3 { + &.has-3rd-divider:not(.has-1st-divider)::before, + &.has-3rd-divider:not(.has-2nd-divider)::after { + @content; + } + } + } @else { + // for smaller screens, dividers are positioned as pseudo elements at column level + @if $divider-order == 1 { + &.has-1st-divider .p-equal-height-row__col::before { + @content; + } + } + + @if $divider-order == 2 { + &.has-2nd-divider .p-equal-height-row__col::after { + @content; + } + } + + @if $divider-order == 3 { + &.has-3rd-divider:not(.has-1st-divider) .p-equal-height-row__col::before, + &.has-3rd-divider:not(.has-2nd-divider) .p-equal-height-row__col::after { + @content; + } + } + } +} + +@mixin divider-styles($large-screen: false) { + // For each row or column grid we only have access to two pseudo elements + // if 1st-divider (::before) is present, assume 2nd-divider (::after) isn't, then 3rd-divider must be (::after) + // if 2nd-divider (::after) is present, assume 1st-divider (::before) isn't, then 3rd-divider must be (::before) + @if $large-screen { + &.has-1st-divider::before, + &.has-2nd-divider::after, + &.has-3rd-divider:not(.has-1st-divider)::before, + &.has-3rd-divider:not(.has-2nd-divider)::after { + @content; + } + } @else { + // For smaller screens, the divider pseudo elements are inserted at the column level + &.has-1st-divider .p-equal-height-row__col::before, + &.has-2nd-divider .p-equal-height-row__col::after, + &.has-3rd-divider:not(.has-1st-divider) .p-equal-height-row__col::before, + &.has-3rd-divider:not(.has-2nd-divider) .p-equal-height-row__col::after { + @content; + } + } +} + +@mixin vf-p-equal-height-row { + .p-equal-height-row { + @extend %vf-row; + position: relative; + + .p-equal-height-row__col { + // smaller screens each column will have border top by default + border-top-color: $colors--theme--border-default; + border-top-style: solid; + border-top-width: 1px; + display: grid; + grid-column: span $grid-columns-small; + grid-row: span 4; + grid-template-rows: subgrid; + margin-top: -1px; + position: relative; + + @media screen and ($breakpoint-small <= width < $breakpoint-large) { + grid-column: span $grid-columns-medium; + grid-template-columns: subgrid; + + // for medium screen, each column item will take half of the available cols from the parent grid + .p-equal-height-row__item { + grid-column: span calc($grid-columns-medium / 2); + } + + // for medium screen, position the first column item on the left of the grid + .p-equal-height-row__item:first-child { + grid-row: span 3; + } + } + + @media screen and (width >= $breakpoint-large) { + border: none; + grid-column: span calc($grid-columns / 4); + } + } + + // divider styles + @include divider-styles($large-screen: false) { + @extend %vf-pseudo-border; + } + + // remove row level dividers for smaller screen sizes + @include divider-styles($large-screen: true) { + @extend %vf-pseudo-border; + display: none; + } + + @include position-divider-by-order-in-grid(1) { + grid-row: 2; + } + + @include position-divider-by-order-in-grid(2) { + grid-row: 3; + } + + @include position-divider-by-order-in-grid(3) { + grid-row: 4; + } + + @media screen and ($breakpoint-small <= width < $breakpoint-large) { + // We don't need to insert divider below item-1 for medium screen size since item-1 gets positioned on the left + @include position-divider-by-order-in-grid(1) { + display: none; + } + + @include position-divider-by-order-in-grid(2) { + grid-column: 4 / 7; + grid-row: 2; + } + + @include position-divider-by-order-in-grid(3) { + grid-column: 4 / 7; + grid-row: 3; + } + } + + @media screen and (width >= $breakpoint-large) { + // remove column level dividers for large screen sizes + @include divider-styles($large-screen: false) { + display: none; + } + + @include divider-styles($large-screen: true) { + display: block; + grid-column-end: span 12; + grid-column-start: 1; + margin: auto; + } + + @include position-divider-by-order-in-grid(1, $large-screen: true) { + grid-row: 2; + } + + @include position-divider-by-order-in-grid(2, $large-screen: true) { + grid-row: 3; + } + + @include position-divider-by-order-in-grid(3, $large-screen: true) { + grid-row: 4; + } + } + } + + // support for 25-75 split on large screen size for this pattern + .row--25-75-on-large > .col, + .row > .col-9 { + & .p-equal-height-row { + grid-template-columns: repeat($grid-columns-small, minmax(0, 1fr)); + + @media screen and ($breakpoint-small <= width < $breakpoint-large) { + grid-template-columns: repeat($grid-columns-medium, minmax(0, 1fr)); + } + + @media screen and (width >= $breakpoint-large) { + grid-template-columns: repeat(9, minmax(0, 1fr)); + } + } + } +} diff --git a/scss/_vanilla.scss b/scss/_vanilla.scss index ae5e5499e1..e290cf0e6b 100644 --- a/scss/_vanilla.scss +++ b/scss/_vanilla.scss @@ -4,18 +4,19 @@ @import 'patterns_accordion'; @import 'patterns_article-pagination'; +@import 'patterns_badge'; @import 'patterns_breadcrumbs'; @import 'patterns_buttons'; @import 'patterns_card'; @import 'patterns_chip'; -@import 'patterns_badge'; @import 'patterns_code-snippet'; @import 'patterns_contextual-menu'; @import 'patterns_divider'; +@import 'patterns_equal-height-row'; @import 'patterns_form-help-text'; -@import 'patterns_form-validation'; -@import 'patterns_form-tick-elements'; @import 'patterns_form-password-toggle'; +@import 'patterns_form-tick-elements'; +@import 'patterns_form-validation'; @import 'patterns_forms'; @import 'patterns_grid'; @import 'patterns_heading-icon'; @@ -39,22 +40,22 @@ @import 'patterns_search-and-filter'; @import 'patterns_search-box'; @import 'patterns_section'; +@import 'patterns_segmented-control'; @import 'patterns_separator'; -@import 'patterns_side-navigation'; @import 'patterns_side-navigation-expandable'; +@import 'patterns_side-navigation'; @import 'patterns_slider'; @import 'patterns_status-label'; @import 'patterns_strip'; +@import 'patterns_suru'; @import 'patterns_switch'; -@import 'patterns_segmented-control'; -@import 'patterns_table-icons'; @import 'patterns_table-expanding'; -@import 'patterns_table-of-contents'; +@import 'patterns_table-icons'; @import 'patterns_table-mobile-card'; +@import 'patterns_table-of-contents'; @import 'patterns_table-sortable'; @import 'patterns_tabs'; @import 'patterns_tooltips'; -@import 'patterns_suru'; // Layouts @import 'layouts_application'; @@ -96,22 +97,23 @@ // Patterns @include vf-p-accordion; @include vf-p-article-pagination; + @include vf-p-badge; @include vf-p-breadcrumbs; @include vf-p-buttons; @include vf-p-card; @include vf-p-chip; - @include vf-p-section; - @include vf-p-badge; @include vf-p-code-snippet; @include vf-p-contextual-menu; @include vf-p-divider; + @include vf-p-equal-height-row; @include vf-p-form-help-text; - @include vf-p-form-validation; @include vf-p-form-tick-elements; + @include vf-p-form-validation; @include vf-p-forms; @include vf-p-grid; @include vf-p-heading-icon; @include vf-p-headings; + @include vf-p-section; @include vf-p-form-password-toggle; @include vf-p-icons; diff --git a/scss/standalone/patterns_equal-height-row.scss b/scss/standalone/patterns_equal-height-row.scss new file mode 100644 index 0000000000..6be926283b --- /dev/null +++ b/scss/standalone/patterns_equal-height-row.scss @@ -0,0 +1,11 @@ +@import '../vanilla'; +@include vf-base; + +// dependencies needed for examples +@include vf-p-buttons; +@include vf-p-media-container; +@include vf-p-headings; + +// vf-p-grid is needed for this pattern to work +@include vf-p-grid; +@include vf-p-equal-height-row; diff --git a/side-navigation.yaml b/side-navigation.yaml index 8a42c7e09c..9a56582130 100644 --- a/side-navigation.yaml +++ b/side-navigation.yaml @@ -30,6 +30,8 @@ subheadings: - title: Accordion url: /docs/patterns/accordion + - title: Equal height row + url: /docs/patterns/equal-height-row - title: Badge url: /docs/patterns/badge - title: Breadcrumbs diff --git a/templates/docs/examples/patterns/equal-height-row/25-75-grid.html b/templates/docs/examples/patterns/equal-height-row/25-75-grid.html new file mode 100644 index 0000000000..25f4bc4c26 --- /dev/null +++ b/templates/docs/examples/patterns/equal-height-row/25-75-grid.html @@ -0,0 +1,106 @@ +{% extends "_layouts/examples.html" %} +{% block title %}Equal height row / Use in 25-75 grid{% endblock %} + +{% block standalone_css %}patterns_equal-height-row{% endblock %} + +{% block content %} + +
+ +
+
+
+ +

Unleash the power of GPU: Ubuntu WorkSpaces now support Graphics G4dn bundles

+
+

A few months ago, the OpenSSL Project announced the end of life of OpenSSL + 1.1.1. It is used by thousands of software components included in Ubuntu 18.04 LTS and Ubuntu 20.04 LTS, with + many organisations relying on version 1.1.1....

+ +
+
+ +

Canonical joins SOAFEE SIG Ubuntu Desktop 23.10:Mantic Minotaur deep dive

+
+

If you've been following my previous blog posts, you already know that + the automotive industry is changing faster than ever. Updating software and firmware in vehicles is one area + that's particularly challenging and in flux....

+ +
+
+ +

Canonical joins SOAFEE SIG Ubuntu Desktop 23.10:Mantic Minotaur deep dive

+
+

Today, around 96% of software projects utilize open source in some way. The + web team here at Canonical is passionate about Open source. We lead with an open-by-default approach and so + almost everything we do and work on can be found publicly on the Canonical Github org.

+ +
+
+
+
+ +

Unleash the power of GPU: Ubuntu WorkSpaces now support Graphics G4dn bundles

+
+

A few months ago, the OpenSSL Project announced the end of life of OpenSSL + 1.1.1. It is used by thousands of software components included in Ubuntu 18.04 LTS and Ubuntu 20.04 LTS, with + many organisations relying on version 1.1.1....

+ +
+
+ +

Canonical joins SOAFEE SIG Ubuntu Desktop 23.10:Mantic Minotaur deep dive

+
+

If you've been following my previous blog posts, you already know that + the automotive industry is changing faster than ever. Updating software and firmware in vehicles is one area + that's particularly challenging and in flux....

+ +
+
+ +

Canonical joins SOAFEE SIG Ubuntu Desktop 23.10:Mantic Minotaur deep dive

+
+

Today, around 96% of software projects utilize open source in some way. The + web team here at Canonical is passionate about Open source. We lead with an open-by-default approach and so + almost everything we do and work on can be found publicly on the Canonical Github org.

+ +
+
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/templates/docs/examples/patterns/equal-height-row/4-items-per-column.html b/templates/docs/examples/patterns/equal-height-row/4-items-per-column.html new file mode 100644 index 0000000000..3e86211e19 --- /dev/null +++ b/templates/docs/examples/patterns/equal-height-row/4-items-per-column.html @@ -0,0 +1,145 @@ +{% extends "_layouts/examples.html" %} +{% block title %}Equal height row / 4 item columns{% endblock %} + +{% block standalone_css %}patterns_equal-height-row{% endblock %} + +{% block content %} + +
+ +
+
+
+
+
+ +
+
+ +

+ A few months ago, the OpenSSL Project announced the end of life of OpenSSL 1.1.1. It + is used by thousands of software components included in Ubuntu 18.04 LTS and Ubuntu + 20.04 LTS, with many organisations relying on version 1.1.1.... +

+
+
+ +
+
+
+
+
+
+ +
+
+ +

+ A few months ago, the OpenSSL Project announced the end of life of OpenSSL 1.1.1. It + is used by thousands of software components included in Ubuntu 18.04 LTS and Ubuntu + 20.04 LTS, with many organisations relying on version 1.1.1.... +

+
+
+ +
+
+
+
+
+ +
+ +

+ A few months ago, the OpenSSL Project announced the end of life of OpenSSL 1.1.1. It + is used by thousands of software components included in Ubuntu 18.04 LTS and Ubuntu + 20.04 LTS, with many organisations relying on version 1.1.1.... +

+
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +

+ A few months ago, the OpenSSL Project announced the end of life of OpenSSL 1.1.1. It + is used by thousands of software components included in Ubuntu 18.04 LTS and Ubuntu + 20.04 LTS, with many organisations relying on version 1.1.1.... +

+
+
+ +
+
+
+
+
+
+ +
+
+ +

+ A few months ago, the OpenSSL Project announced the end of life of OpenSSL 1.1.1. It + is used by thousands of software components included in Ubuntu 18.04 LTS and Ubuntu + 20.04 LTS, with many organisations relying on version 1.1.1.... +

+
+
+ +
+
+
+
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/templates/docs/examples/patterns/equal-height-row/default.html b/templates/docs/examples/patterns/equal-height-row/default.html new file mode 100644 index 0000000000..f40a25f6fd --- /dev/null +++ b/templates/docs/examples/patterns/equal-height-row/default.html @@ -0,0 +1,53 @@ +{% extends "_layouts/examples.html" %} +{% block title %}Equal height row / Default{% endblock %} + +{% block standalone_css %}patterns_equal-height-row{% endblock %} + +{% block content %} + +
+
+
+ Some title +
+

Use the Ubuntu terminal and run Linux applications on Windows. Use the Ubuntu + terminal + and run Linux applications on Windows.

+ +
+
+
+ Some Title +
+

Use your Raspberry Pi as a desktop, server or IoT device with Ubuntu.

+ +
+
+
+ Some Title +
+

Spin up Ubuntu VMs on Windows, Mac and Linux.

+ +
+
+
+ Some Title +
+

Fast, dense, and secure container and VM management at any scale.

+ +
+
+ +{% endblock %} \ No newline at end of file diff --git a/templates/docs/examples/patterns/equal-height-row/full-screen-dividers.html b/templates/docs/examples/patterns/equal-height-row/full-screen-dividers.html new file mode 100644 index 0000000000..f1fe999adc --- /dev/null +++ b/templates/docs/examples/patterns/equal-height-row/full-screen-dividers.html @@ -0,0 +1,70 @@ +{% extends "_layouts/examples.html" %} +{% block title %}Equal height row / Full screen dividers{% endblock %} + +{% block standalone_css %}patterns_equal-height-row{% endblock %} + +{% block content %} + +
+
+
+
+ +
+
+

Use the Ubuntu terminal and run Linux applications on Windows. Use the + Ubuntu + terminal + and run Linux applications on Windows.

+ +
+
+
+
+ +
+
+

Use your Raspberry Pi as a desktop, server or IoT device with Ubuntu.

+ +
+
+
+
+ +
+
+

Spin up Ubuntu VMs on Windows, Mac and Linux.

+ +
+
+
+
+ +
+
+

Fast, dense, and secure container and VM management at any scale.

+ +
+
+ +{% endblock %} \ No newline at end of file diff --git a/templates/docs/patterns/equal-height-row.md b/templates/docs/patterns/equal-height-row.md new file mode 100644 index 0000000000..06a2cb61d0 --- /dev/null +++ b/templates/docs/patterns/equal-height-row.md @@ -0,0 +1,99 @@ +--- +wrapper_template: '_layouts/docs.html' +context: + title: Equal height row | Components +--- + +The equal height row component aims to provide consistent alignment for grid items within a row format. This is achieved using the CSS `subgrid` feature which allows column grids to share the same layout used in the parent row grid. + +This component is an extension of the [grid component](/docs/patterns/grid). There are two ways to use this component: + +1. Used as a four column row grid (`.p-equal-height-row`). Each column (`.p-equal-height-row__col`) within the row is a css grid, and may have up to four grid items (`.p-equal-height-row__item`). + +2. Nest inside the `25-75` grid pattern on large screen size (`.row--25-75-on-large`). The row (`.p-equal-height-row`) should be placed within the 75% container with a maximum of three columns. + +In addition to enforcing column grid items alignment within each row, responsive behaviour is provided out of the box as shown below: + + + + + + + + + + + + + + + + + + + + + + +
Screen size (px)Behaviour
Less than $breakpoint-smallEach column spans across the entire parent grid. Column items are vertically stacked.
$breakpoint-small - $breakpoint-largeEach column spans across the entire parent grid. The first item within each column is placed on the left of the other column items.
Greater than $breakpoint-largeColumns within the row are displayed horizontally. Column items are vertically stacked.
+ +The below sections provides examples for using this component to achieve common design patterns. + +## Four column row pattern + + + +## Full screen dividers + +You can insert dividers that span across all columns within a row using `.has-1st-divider`, `.has-2nd-divider` and `.has-3rd-divider`. + +
+
+
Note:
+

For smaller screen sizes i.e. < $breakpoint-large the divider will appear below relevant items within each column.

+
+
+ +
+
+

You may only have two dividers maximum. For example, if you have .has-1st-divider and .has-2nd-divider set for the row, then .has-3rd-divider will not be shown. This is a limitation due to usage of pseudo elements for visualising dividers that is capable of spanning across grid gaps.

+
+
+ + + +## 25-75 grid pattern + +You may use the equal height row component within a 25-75 grid layout for large screen sizes. You should place the equal height row component with a maximum of three columns inside the 75% container when using this pattern. + + + +## Four items per column pattern + +Each column can have up to 4 items. + + + +## Import + +To import just this component into your project, copy the snippet below and include it in your main Sass file. + +```scss +// import Vanilla and include base mixins +// this only needs to happen once in a given project +@import 'vanilla-framework'; +@include vf-base; + +@include vf-p-grid; +@include vf-p-equal-height-row; +``` + +For more information see [Customising Vanilla](/docs/customising-vanilla/) in your projects, which includes overrides and importing instructions.