Skin 10.x: Migrating to Grid
Last modified by Vincent Massol on 2024/02/26 17:57
Description
The purpose of this investigation is to evaluate the difficulties, advantages and implementability of switching from Bootstrap to a Grid defined skin.
Comparison
Layout Definition
This is an example of how we have / could have the current layout variations defined in Flamingo skin using multiple techniques:
Limitations
- CSS Variables need to be inside a :root {} or other selector declaration, compared to LESS variables that are top level
- Less4jException: Could not compile less error. Cannot use CSS variables inside our .LESS files. Gets a
Cannot use fr units in calc(). In the demo I'm using px, but we would need to calculated in % for panels sizes, using the formula:
the width of each column = (width of viewport / number of columns) * 1%
Layout Variations
LESS + Bootstrap 3 mixins
@main-padding: @grid-gutter-width * 2;
#body {
// Both left and right panels are displayed
&.content {
// Left panels are small
&.panel-left-width-Small {
.main {
.make-md-column-push(1);
}
// Left panels are small and right panels are small
&.panel-right-width-Small {
.main {
.make-md-column(10, @main-padding);
}
#leftPanels {
.make-md-column-pull(10);
}
}
// Left panels are small and right panels are medium
&.panel-right-width-Medium {
.main {
.make-md-column(9, @main-padding);
}
#leftPanels {
.make-md-column-pull(9);
}
}
// Left panels are small and right panels are large
&.panel-right-width-Large {
.main {
.make-md-column(8, @main-padding);
}
#leftPanels {
.make-md-column-pull(8);
}
}
}
// Left panels are medium
&.panel-left-width-Medium {
.main {
.make-md-column-push(2);
}
// Left panels are medium and right panels are small
&.panel-right-width-Small {
.main {
.make-md-column(9, @main-padding);
}
#leftPanels {
.make-md-column-pull(9);
}
}
// Left panels are medium and right panels are medium
&.panel-right-width-Medium {
.main {
.make-md-column(8, @main-padding);
}
#leftPanels {
.make-md-column-pull(8);
}
}
// Left panels are medium and right panels are large
&.panel-right-width-Large {
.main {
.make-md-column(7, @main-padding);
}
#leftPanels {
.make-md-column-pull(7);
}
}
}
// // Left panels are large
&.panel-left-width-Large {
.main {
.make-md-column-push(3);
}
// Left panels are large and right panels are small
&.panel-right-width-Small {
.main {
.make-md-column(8, @main-padding);
}
#leftPanels {
.make-md-column-pull(8);
}
}
// Left panels are large and right panels are medium
&.panel-right-width-Medium {
.main {
.make-md-column(7, @main-padding);
}
#leftPanels {
.make-md-column-pull(7);
}
}
// Left panels are large and right panels are large
&.panel-right-width-Large {
.main {
.make-md-column(6, @main-padding);
}
#leftPanels {
.make-md-column-pull(6);
}
}
}
}
// Only right panels
&.hideleft {
&.panel-right-width-Small {
.main {
.make-md-column(11, @main-padding);
}
}
&.panel-right-width-Medium {
.main {
.make-md-column(10, @main-padding);
}
}
&.panel-right-width-Large {
.main {
.make-md-column(9, @main-padding);
}
}
}
// Only left panels
&.hideright {
&.panel-left-width-Small {
.main {
.make-md-column(11, @main-padding);
.make-md-column-push(1);
}
#leftPanels {
.make-md-column-pull(11);
}
}
&.panel-left-width-Medium {
.main {
.make-md-column(10, @main-padding);
.make-md-column-push(2);
}
#leftPanels {
.make-md-column-pull(10);
}
}
&.panel-left-width-Large {
.main {
.make-md-column(9, @main-padding);
.make-md-column-push(3);
}
#leftPanels {
.make-md-column-pull(9);
}
}
}
// No Panels
&.hidelefthideright {
.main {
.make-md-column(12, @main-padding);
}
}
&.panel-left-width-Small {
#leftPanels {
.make-md-column(1);
}
}
&.panel-left-width-Medium {
#leftPanels {
.make-md-column(2);
}
}
&.panel-left-width-Large {
#leftPanels {
.make-md-column(3);
}
}
&.panel-right-width-Small {
#rightPanels, #editPanels {
.make-md-column(1);
}
}
&.panel-right-width-Medium {
#rightPanels, #editPanels {
.make-md-column(2);
}
}
&.panel-right-width-Large {
#rightPanels, #editPanels {
.make-md-column(3);
}
}
}
#leftPanels, #rightPanels {
.make-xs-column(12);
}
#body {
// Both left and right panels are displayed
&.content {
// Left panels are small
&.panel-left-width-Small {
.main {
.make-md-column-push(1);
}
// Left panels are small and right panels are small
&.panel-right-width-Small {
.main {
.make-md-column(10, @main-padding);
}
#leftPanels {
.make-md-column-pull(10);
}
}
// Left panels are small and right panels are medium
&.panel-right-width-Medium {
.main {
.make-md-column(9, @main-padding);
}
#leftPanels {
.make-md-column-pull(9);
}
}
// Left panels are small and right panels are large
&.panel-right-width-Large {
.main {
.make-md-column(8, @main-padding);
}
#leftPanels {
.make-md-column-pull(8);
}
}
}
// Left panels are medium
&.panel-left-width-Medium {
.main {
.make-md-column-push(2);
}
// Left panels are medium and right panels are small
&.panel-right-width-Small {
.main {
.make-md-column(9, @main-padding);
}
#leftPanels {
.make-md-column-pull(9);
}
}
// Left panels are medium and right panels are medium
&.panel-right-width-Medium {
.main {
.make-md-column(8, @main-padding);
}
#leftPanels {
.make-md-column-pull(8);
}
}
// Left panels are medium and right panels are large
&.panel-right-width-Large {
.main {
.make-md-column(7, @main-padding);
}
#leftPanels {
.make-md-column-pull(7);
}
}
}
// // Left panels are large
&.panel-left-width-Large {
.main {
.make-md-column-push(3);
}
// Left panels are large and right panels are small
&.panel-right-width-Small {
.main {
.make-md-column(8, @main-padding);
}
#leftPanels {
.make-md-column-pull(8);
}
}
// Left panels are large and right panels are medium
&.panel-right-width-Medium {
.main {
.make-md-column(7, @main-padding);
}
#leftPanels {
.make-md-column-pull(7);
}
}
// Left panels are large and right panels are large
&.panel-right-width-Large {
.main {
.make-md-column(6, @main-padding);
}
#leftPanels {
.make-md-column-pull(6);
}
}
}
}
// Only right panels
&.hideleft {
&.panel-right-width-Small {
.main {
.make-md-column(11, @main-padding);
}
}
&.panel-right-width-Medium {
.main {
.make-md-column(10, @main-padding);
}
}
&.panel-right-width-Large {
.main {
.make-md-column(9, @main-padding);
}
}
}
// Only left panels
&.hideright {
&.panel-left-width-Small {
.main {
.make-md-column(11, @main-padding);
.make-md-column-push(1);
}
#leftPanels {
.make-md-column-pull(11);
}
}
&.panel-left-width-Medium {
.main {
.make-md-column(10, @main-padding);
.make-md-column-push(2);
}
#leftPanels {
.make-md-column-pull(10);
}
}
&.panel-left-width-Large {
.main {
.make-md-column(9, @main-padding);
.make-md-column-push(3);
}
#leftPanels {
.make-md-column-pull(9);
}
}
}
// No Panels
&.hidelefthideright {
.main {
.make-md-column(12, @main-padding);
}
}
&.panel-left-width-Small {
#leftPanels {
.make-md-column(1);
}
}
&.panel-left-width-Medium {
#leftPanels {
.make-md-column(2);
}
}
&.panel-left-width-Large {
#leftPanels {
.make-md-column(3);
}
}
&.panel-right-width-Small {
#rightPanels, #editPanels {
.make-md-column(1);
}
}
&.panel-right-width-Medium {
#rightPanels, #editPanels {
.make-md-column(2);
}
}
&.panel-right-width-Large {
#rightPanels, #editPanels {
.make-md-column(3);
}
}
}
#leftPanels, #rightPanels {
.make-xs-column(12);
}
LESS + Grid
@supports (display: grid) {
#contentcolumn {
grid-area: content;
}
#leftPanels {
grid-area: leftpanels;
}
#rightPanels {
grid-area: rightpanels;
}
#contentcontainer {
display: grid;
grid: "leftpanels content rightpanels" / auto auto auto;
}
body {
&.panel-left-width-Small.panel-right-width-Small {
#contentcontainer {
grid-template-columns: 1fr 10fr 1fr;
}
}
&.panel-left-width-Small.panel-right-width-Medium {
#contentcontainer {
grid-template-columns: 1fr 9fr 2fr;
}
}
&.panel-left-width-Small.panel-right-width-Large {
#contentcontainer {
grid-template-columns: 1fr 8fr 3fr;
}
}
&.panel-left-width-Medium.panel-right-width-Small {
#contentcontainer {
grid-template-columns: 2fr 9fr 1fr;
}
}
&.panel-left-width-Medium.panel-right-width-Medium {
#contentcontainer {
grid-template-columns: 2fr 8fr 2fr;
}
}
&.panel-left-width-Medium.panel-right-width-Large {
#contentcontainer {
grid-template-columns: 2fr 7fr 3fr;
}
}
&.panel-left-width-Large.panel-right-width-Small {
#contentcontainer {
grid-template-columns: 3fr 8fr 1fr;
}
}
&.panel-left-width-Large.panel-right-width-Medium {
#contentcontainer {
grid-template-columns: 3fr 7fr 2fr;
}
}
&.panel-left-width-Large.panel-right-width-Large {
#contentcontainer {
grid-template-columns: 3fr 6fr 3fr;
}
}
&.hideright {
&.panel-left-width-Small {
#contentcontainer {
grid-template-columns: 1fr 11fr 0;
}
}
&.panel-left-width-Medium {
#contentcontainer {
grid-template-columns: 2fr 10fr 0;
}
}
&.panel-left-width-Large {
#contentcontainer {
grid-template-columns: 3fr 9fr 0;
}
}
}
&.hideleft {
&.panel-right-width-Small {
#contentcontainer {
grid-template-columns: 0 11fr 1fr;
}
}
&.panel-right-width-Medium {
#contentcontainer {
grid-template-columns: 0 10fr 2fr;
}
}
&.panel-right-width-Large {
#contentcontainer {
grid-template-columns: 0 9fr 3fr;
}
}
}
}
#body {
&.hidelefthideright {
#contentcontainer {
grid-template-columns: 0 12fr 0;
}
}
}
}
#contentcolumn {
grid-area: content;
}
#leftPanels {
grid-area: leftpanels;
}
#rightPanels {
grid-area: rightpanels;
}
#contentcontainer {
display: grid;
grid: "leftpanels content rightpanels" / auto auto auto;
}
body {
&.panel-left-width-Small.panel-right-width-Small {
#contentcontainer {
grid-template-columns: 1fr 10fr 1fr;
}
}
&.panel-left-width-Small.panel-right-width-Medium {
#contentcontainer {
grid-template-columns: 1fr 9fr 2fr;
}
}
&.panel-left-width-Small.panel-right-width-Large {
#contentcontainer {
grid-template-columns: 1fr 8fr 3fr;
}
}
&.panel-left-width-Medium.panel-right-width-Small {
#contentcontainer {
grid-template-columns: 2fr 9fr 1fr;
}
}
&.panel-left-width-Medium.panel-right-width-Medium {
#contentcontainer {
grid-template-columns: 2fr 8fr 2fr;
}
}
&.panel-left-width-Medium.panel-right-width-Large {
#contentcontainer {
grid-template-columns: 2fr 7fr 3fr;
}
}
&.panel-left-width-Large.panel-right-width-Small {
#contentcontainer {
grid-template-columns: 3fr 8fr 1fr;
}
}
&.panel-left-width-Large.panel-right-width-Medium {
#contentcontainer {
grid-template-columns: 3fr 7fr 2fr;
}
}
&.panel-left-width-Large.panel-right-width-Large {
#contentcontainer {
grid-template-columns: 3fr 6fr 3fr;
}
}
&.hideright {
&.panel-left-width-Small {
#contentcontainer {
grid-template-columns: 1fr 11fr 0;
}
}
&.panel-left-width-Medium {
#contentcontainer {
grid-template-columns: 2fr 10fr 0;
}
}
&.panel-left-width-Large {
#contentcontainer {
grid-template-columns: 3fr 9fr 0;
}
}
}
&.hideleft {
&.panel-right-width-Small {
#contentcontainer {
grid-template-columns: 0 11fr 1fr;
}
}
&.panel-right-width-Medium {
#contentcontainer {
grid-template-columns: 0 10fr 2fr;
}
}
&.panel-right-width-Large {
#contentcontainer {
grid-template-columns: 0 9fr 3fr;
}
}
}
}
#body {
&.hidelefthideright {
#contentcontainer {
grid-template-columns: 0 12fr 0;
}
}
}
}
CSS + Grid + CSS Variables
@supports (display: grid) {
#contentcolumn {
grid-area: content;
}
#leftPanels {
grid-area: leftpanels;
}
#rightPanels {
grid-area: rightpanels;
}
#contentcontainer {
display: grid;
grid: "leftpanels content rightpanels" / auto auto auto;
}
:root {
--grid-small-column: 1;
--grid-medium-column: 2;
--grid-large-column: 3;
/* The calculations work good with px, but not with fr. We could adapt to have a % solution */
--grid-unit: 1fr;
}
#body.panel-left-width-Small #contentcontainer {
--grid-leftPanels: calc(var(--grid-small-column) * var(--grid-unit));
}
#body.panel-left-width-Medium #contentcontainer {
--grid-leftPanels: calc(var(--grid-medium-column) * var(--grid-unit));
}
#body.panel-left-width-Large #contentcontainer {
--grid-leftPanels: calc(var(--grid-large-column) * var(--grid-unit));
}
#body.panel-right-width-Small #contentcontainer {
--grid-rightPanels: calc(var(--grid-small-column) * var(--grid-unit));
}
#body.panel-right-width-Medium #contentcontainer {
--grid-rightPanels: calc(var(--grid-medium-column) * var(--grid-unit));
}
#body.panel-right-width-Large #contentcontainer {
--grid-rightPanels: calc(var(--grid-large-column) * var(--grid-unit));
}
#body.hideleft #contentcontainer {
--grid-leftPanels: 0;
}
#body.hideright #contentcontainer {
--grid-rightPanels: 0;
}
#body.hidelefthideright #contentcontainer {
--grid-leftPanels: 0;
--grid-rightPanels: 0;
}
#contentcontainer {
--grid-content: auto;
grid-template-columns: var(--grid-leftPanels) var(--grid-content) var(--grid-rightPanels);
}
}
#contentcolumn {
grid-area: content;
}
#leftPanels {
grid-area: leftpanels;
}
#rightPanels {
grid-area: rightpanels;
}
#contentcontainer {
display: grid;
grid: "leftpanels content rightpanels" / auto auto auto;
}
:root {
--grid-small-column: 1;
--grid-medium-column: 2;
--grid-large-column: 3;
/* The calculations work good with px, but not with fr. We could adapt to have a % solution */
--grid-unit: 1fr;
}
#body.panel-left-width-Small #contentcontainer {
--grid-leftPanels: calc(var(--grid-small-column) * var(--grid-unit));
}
#body.panel-left-width-Medium #contentcontainer {
--grid-leftPanels: calc(var(--grid-medium-column) * var(--grid-unit));
}
#body.panel-left-width-Large #contentcontainer {
--grid-leftPanels: calc(var(--grid-large-column) * var(--grid-unit));
}
#body.panel-right-width-Small #contentcontainer {
--grid-rightPanels: calc(var(--grid-small-column) * var(--grid-unit));
}
#body.panel-right-width-Medium #contentcontainer {
--grid-rightPanels: calc(var(--grid-medium-column) * var(--grid-unit));
}
#body.panel-right-width-Large #contentcontainer {
--grid-rightPanels: calc(var(--grid-large-column) * var(--grid-unit));
}
#body.hideleft #contentcontainer {
--grid-leftPanels: 0;
}
#body.hideright #contentcontainer {
--grid-rightPanels: 0;
}
#body.hidelefthideright #contentcontainer {
--grid-leftPanels: 0;
--grid-rightPanels: 0;
}
#contentcontainer {
--grid-content: auto;
grid-template-columns: var(--grid-leftPanels) var(--grid-content) var(--grid-rightPanels);
}
}