Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit 99d2bbd

Browse files
authored
feat(layout-grid): parameterize layout grid (#795)
BREAKING CHANGE: the css custom properties for customize margins and gutters are exposed in format of `mdc-layout-grid-margin-#{$size}`, where valid sizes are `desktop`, `tablet` and `phone`. The old name `mdc-layout-grid-margin` and `mdc-layout-grid-gutter` is no longer available in the new version. Sass variables change from single numeric value to Sass map to accomendate margins and gutters for different screens as well. Visually, the default value of margins and gutters change from 16px to 24px on desktop, while remain the same on tablet and mobile.
1 parent 0471f1f commit 99d2bbd

File tree

5 files changed

+171
-81
lines changed

5 files changed

+171
-81
lines changed

demos/layout-grid.html

Lines changed: 89 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -121,28 +121,73 @@
121121
</section>
122122

123123
<section class="examples">
124-
125-
<div class="demo-controls">
126-
Margin:
127-
<select id="margin">
128-
<option value="8px">8px</option>
129-
<option value="16px" selected>16px</option>
130-
<option value="24px">24px</option>
131-
<option value="40px">40px</option>
132-
</select>
133-
134-
<br>
135-
136-
Gutter:
137-
<select id="gutter">
138-
<option value="8px">8px</option>
139-
<option value="16px" selected>16px</option>
140-
<option value="24px">24px</option>
141-
<option value="40px">40px</option>
142-
</select>
124+
<div class="mdc-layout-grid">
125+
<div class="mdc-layout-grid__cell">
126+
<div class="demo-controls">
127+
Desktop Margin:
128+
<select id="desktop-margin">
129+
<option value="8px">8px</option>
130+
<option value="16px">16px</option>
131+
<option value="24px" selected>24px</option>
132+
<option value="40px">40px</option>
133+
</select>
134+
135+
<br>
136+
137+
Desktop Gutter:
138+
<select id="desktop-gutter">
139+
<option value="8px">8px</option>
140+
<option value="16px">16px</option>
141+
<option value="24px" selected>24px</option>
142+
<option value="40px">40px</option>
143+
</select>
144+
</div>
145+
</div>
146+
<div class="mdc-layout-grid__cell">
147+
<div class="demo-controls">
148+
Tablet Margin:
149+
<select id="tablet-margin">
150+
<option value="8px">8px</option>
151+
<option value="16px" selected>16px</option>
152+
<option value="24px">24px</option>
153+
<option value="40px">40px</option>
154+
</select>
155+
156+
<br>
157+
158+
Tablet Gutter:
159+
<select id="tablet-gutter">
160+
<option value="8px">8px</option>
161+
<option value="16px" selected>16px</option>
162+
<option value="24px">24px</option>
163+
<option value="40px">40px</option>
164+
</select>
165+
</div>
166+
</div>
167+
<div class="mdc-layout-grid__cell">
168+
<div class="demo-controls">
169+
Phone Margin:
170+
<select id="phone-margin">
171+
<option value="8px">8px</option>
172+
<option value="16px" selected>16px</option>
173+
<option value="24px">24px</option>
174+
<option value="40px">40px</option>
175+
</select>
176+
177+
<br>
178+
179+
Phone Gutter:
180+
<select id="phone-gutter">
181+
<option value="8px">8px</option>
182+
<option value="16px" selected>16px</option>
183+
<option value="24px">24px</option>
184+
<option value="40px">40px</option>
185+
</select>
186+
</div>
187+
</div>
143188
</div>
144-
<div class="demo-warning"></div>
145189

190+
<div class="demo-warning"></div>
146191

147192
<div class="demo-grid-legend">Grid of 1 column wide items</div>
148193
<div class="demo-grid mdc-layout-grid">
@@ -203,14 +248,32 @@
203248
<script>
204249
(function(global) {
205250
'use strict';
206-
var marginSelect = document.querySelector('#margin');
207-
marginSelect.addEventListener('change', function() {
208-
document.documentElement.style.setProperty('--mdc-layout-grid-margin', marginSelect.value);
251+
var marginSelectDesktop = document.querySelector('#desktop-margin');
252+
marginSelectDesktop.addEventListener('change', function() {
253+
document.documentElement.style.setProperty('--mdc-layout-grid-margin-desktop', marginSelectDesktop.value);
254+
});
255+
256+
var gutterSelectDesktop = document.querySelector('#desktop-gutter');
257+
gutterSelectDesktop.addEventListener('change', function() {
258+
document.documentElement.style.setProperty('--mdc-layout-grid-gutter-desktop', gutterSelectDesktop.value);
259+
});
260+
var marginSelectTablet = document.querySelector('#tablet-margin');
261+
marginSelectTablet.addEventListener('change', function() {
262+
document.documentElement.style.setProperty('--mdc-layout-grid-margin-tablet', marginSelectTablet.value);
263+
});
264+
265+
var gutterSelectTablet = document.querySelector('#tablet-gutter');
266+
gutterSelectTablet.addEventListener('change', function() {
267+
document.documentElement.style.setProperty('--mdc-layout-grid-gutter-tablet', gutterSelectTablet.value);
268+
});
269+
var marginSelectPhone = document.querySelector('#phone-margin');
270+
marginSelectPhone.addEventListener('change', function() {
271+
document.documentElement.style.setProperty('--mdc-layout-grid-margin-phone', marginSelectPhone.value);
209272
});
210273

211-
var gutterSelect = document.querySelector('#gutter');
212-
gutterSelect.addEventListener('change', function() {
213-
document.documentElement.style.setProperty('--mdc-layout-grid-gutter', gutterSelect.value);
274+
var gutterSelectPhone = document.querySelector('#phone-gutter');
275+
gutterSelectPhone.addEventListener('change', function() {
276+
document.documentElement.style.setProperty('--mdc-layout-grid-gutter-phone', gutterSelectPhone.value);
214277
});
215278

216279
var current = document.querySelector('#current');

packages/mdc-layout-grid/README.md

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ there isn't enough room for a cell, it gets moved to the beginning of the next r
4848
The grid has 12 columns in desktop mode (>= 840px), 8 columns in tablet mode (>= 480px), and 4 columns in phone mode
4949
(< 480px). Column widths are variable; margins and gutters are fixed, with columns taking up the remainder of the space.
5050

51-
Margins (the space between the edge of the grid and the edge of the first cell) and gutters (the space between edges of
52-
adjacent cells) are user-definable, with the Material Design spec recommending 8px, 16px, 24px or 40px as the sizes to
53-
choose from. The default margin and gutter are both 16px, but they don't have to be the same size.
51+
Margins (the space between the edge of the grid and the edge of the first cell) and gutters (the space between edges of adjacent cells) can be customized on different devices respectively based on design needs. Layout grids set default margins and gutters to 24px on desktop, 16px on tablet and phone, according to the Material Design spec.
5452

5553
The grid and cells are not styled in any way, serving only for alignment and positioning of elements.
5654

@@ -70,24 +68,36 @@ Behavior for grids containing direct children without the `mdc-layout-grid__cell
7068

7169
### Margins and gutters
7270

73-
The default size for both the margins and gutters in MDC layout grid is 16px.
71+
Layout grids set default margins and gutters to 24px on desktop, 16px on tablet and phone.
7472

75-
You can change the margins and gutters for a grid using the `--mdc-layout-grid-margin` and `--mdc-layout-grid-gutter`
76-
custom properties, respectively. This requires support for CSS custom properties on the end-user's browser.
73+
The Material Design spec recommends 8px, 16px, 24px or 40px as the sizes to choose from, we set those as choices in our demo catalog. However, MDC layout grid doesn't impose any restrictions.
7774

78-
The Material Design spec recommends 8px, 16px, 24px or 40px as the sizes to choose from, but MDC layout grid doesn't
79-
impose any restrictions.
75+
> Note: Due to the implementation of MDC layout grid, it's not possible to use a margin smaller than half of the size
76+
of the gutter, in most browsers. As support for [CSS Grid](https://www.w3.org/TR/css-grid-1/) lands in browsers, this
77+
limitation will go away, as MDC layout grid is progressively enhanced to support it.
78+
79+
80+
#### CSS custom properties
81+
82+
You can change the margins and gutters for a grid using the `--mdc-layout-grid-margin-#{$device}` and `--mdc-layout-grid-gutter-#{$device}` custom properties, respectively. This requires support for CSS custom properties on the end-user's browser.
8083

8184
```css
8285
.my-grid {
83-
--mdc-layout-grid-margin: 40px;
84-
--mdc-layout-grid-gutter: 16px;
86+
--mdc-layout-grid-margin-desktop: 40px;
87+
--mdc-layout-grid-gutter-tablet: 16px;
88+
--mdc-layout-grid-gutter-phone: 8px;
8589
}
8690
```
8791

88-
> Note: Due to the implementation of MDC layout grid, it's not possible to use a margin smaller than half of the size
89-
of the gutter, in most browsers. As support for [CSS Grid](https://www.w3.org/TR/css-grid-1/) lands in browsers, this
90-
limitation will go away, as MDC layout grid is progressively enhanced to support it.
92+
#### Sass variables
93+
94+
You can change the margins and gutters using sass variables if you are compiling from them. MDC layout grid uses sass map `mdc-layout-grid-default-margin` and `mdc-layout-grid-default-gutter` to define margins and gutters on different screen types.
95+
96+
97+
### Max width
98+
99+
MDC layout grids take up the parent element space by default. However, user can set `$mdc-layout-grid-max-width` to restrict the max-width of the layout grid.
100+
91101

92102
### Column spans
93103

@@ -99,12 +109,10 @@ limitation will go away, as MDC layout grid is progressively enhanced to support
99109
</div>
100110
```
101111

102-
Cells have a default span size of 4 columns, with other sizes being possible by applying one of the span classes, of the
103-
form `mdc-layout-grid__cell--span-{columns}`, where `{columns}` is an integer between 1 and 12.
112+
You can set the cells span by applying one of the span classes, of the form `mdc-layout-grid__cell--span-{columns}`, where `{columns}` is an integer between 1 and 12. If the chosen span size is larger than the available number of columns at the current screen size, the cell behaves as if its chosen span size were equal to the available number of columns at that screen size. That is, it takes up the entirety of its row, and no more than that.
113+
114+
If the span classes are not set, `mdc-layout-grid__cell` will fallback to a default span size of 4 columns. You can make it a different number by changing the default value. However, this number needs to be provided at compile time by using sass variable `$mdc-layout-grid-default-column-span`.
104115

105-
If the chosen span size is larger than the available number of columns at the current screen size, the cell behaves as
106-
if its chosen span size were equal to the available number of columns at that screen size. That is, it takes up the
107-
entirety of its row, and no more than that.
108116

109117
### Column spans for specific screen sizes
110118

@@ -126,6 +134,7 @@ In the example above, the first cell has a default span of 6, the second 4, and
126134
the first cell becomes 8 columns wide instead, and the second 6 columns wide. At phone sizes, the third cell becomes 4
127135
columns wide.
128136

137+
129138
### Reordering
130139

131140
By default, items are positioned in the source order. However, you can reorder them by using the
@@ -162,26 +171,28 @@ behavior by using one of the `mdc-layout-grid__cell--align-{position}` alignment
162171
### mdc-layout-grid
163172

164173
```scss
165-
@include mdc-layout-grid(16px, 16px, 1600px);
174+
@include mdc-layout-grid(desktop, 16px, 16px, 1600px);
166175
```
167176

168-
`mdc-layout-grid` defines a grid and should be applied to the container element. The mixin takes three parameters:
177+
`mdc-layout-grid` defines a grid and should be applied to the container element. The mixin takes four parameters:
178+
- `$size`: the target platform: `desktop`, `tablet` or `phone`.
169179
- `$margin`: the size of the grid margin.
170180
- `$gutter`: the size of the gutter between cells.
171181
- `$max-width` (optional): the maximum width of the grid, at which point space stops being distributed by the columns.
172182

173-
Note that the margin and gutter can be overriden at runtime by using the CSS custom properties detailed in the
174-
"Margins and gutters" section under "CSS class usage".
175-
176183
### mdc-layout-grid-cell
177184

178185
```scss
179-
@include mdc-layout-grid-cell(16px, 4);
186+
@include mdc-layout-grid-cell(desktop, 4, 16px);
180187
```
181188

182189
`mdc-layout-grid-cell` defines a cell and should be applied to the cell element. The mixin takes two parameters:
190+
- `$size`: the target platform: `desktop`, `tablet` or `phone`.
191+
- `$default-span` (optional, default 4): how many columns this cell should span (1 to 12).
183192
- `$gutter`: the size of the gutter between cells. Be sure to use the same value as for the parent grid.
184-
- `$span` (optional, default 4): how many columns this cell should span (1 to 12).
193+
194+
> Note even though size is passed in as one of the arguments, it won't apply any `media-query` rules. It is set for using the correct CSS custom properties to overriden the margin and gutter at runtime (See [Margins and gutters](#margins-and-gutters) section for detail).
195+
185196

186197
### mdc-layout-grid-cell-order
187198

packages/mdc-layout-grid/_mixins.scss

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,61 +44,49 @@
4444
}
4545

4646
width: calc(#{$percent} - #{$gutter});
47-
width: calc(#{$percent} - var(--mdc-layout-grid-gutter, #{$gutter}));
47+
width: calc(#{$percent} - var(--mdc-layout-grid-gutter-#{$size}, #{$gutter}));
4848

4949
@supports (display: grid) {
5050
width: auto;
5151
grid-column-end: span min($span, map-get($mdc-layout-grid-columns, $size));
5252
}
5353
}
5454

55-
@mixin mdc-layout-grid-cell-spans_($span, $gutter) {
56-
@each $size in map-keys($mdc-layout-grid-columns) {
57-
@include mdc-layout-grid-media-query_($size) {
58-
@include mdc-layout-grid-cell-span_($size, $span, $gutter);
59-
}
60-
}
61-
}
62-
6355
// Public mixins, meant for developer usage.
64-
@mixin mdc-layout-grid($margin, $gutter, $max-width: null) {
56+
@mixin mdc-layout-grid($size, $margin, $gutter, $max-width: null) {
6557
display: flex;
6658
flex-flow: row wrap;
6759
align-items: stretch;
6860
margin: 0 auto;
6961
box-sizing: border-box;
70-
padding: $margin - $gutter / 2;
71-
padding: calc(var(--mdc-layout-grid-margin, #{$margin}) - var(--mdc-layout-grid-gutter, #{$gutter}) / 2);
7262

7363
@if $max-width {
7464
max-width: $max-width;
7565
}
7666

67+
padding: $margin - $gutter / 2;
68+
padding: calc(var(--mdc-layout-grid-margin-#{$size}, #{$margin}) - var(--mdc-layout-grid-gutter-#{$size}, #{$gutter}) / 2);
69+
7770
@supports (display: grid) {
7871
display: grid;
7972
grid-gap: $gutter;
80-
grid-gap: var(--mdc-layout-grid-gutter, $gutter);
73+
grid-gap: var(--mdc-layout-grid-gutter-#{$size}, $gutter);
8174
padding: $margin;
82-
padding: var(--mdc-layout-grid-margin, #{$margin});
83-
84-
@each $size in map-keys($mdc-layout-grid-columns) {
85-
@include mdc-layout-grid-media-query_($size) {
86-
grid-template-columns: repeat(map-get($mdc-layout-grid-columns, $size), minmax(0, 1fr));
87-
}
88-
}
75+
padding: var(--mdc-layout-grid-margin-#{$size}, #{$margin});
76+
grid-template-columns: repeat(map-get($mdc-layout-grid-columns, $size), minmax(0, 1fr));
8977
}
9078
}
9179

92-
@mixin mdc-layout-grid-cell($gutter, $span: 4) {
93-
margin: $gutter / 2;
94-
margin: calc(var(--mdc-layout-grid-gutter, #{$gutter}) / 2);
80+
@mixin mdc-layout-grid-cell($size, $default-span, $gutter) {
9581
box-sizing: border-box;
82+
margin: $gutter / 2;
83+
margin: calc(var(--mdc-layout-grid-gutter-#{$size}, #{$gutter}) / 2);
9684

9785
@supports (display: grid) {
9886
margin: 0;
9987
}
10088

101-
@include mdc-layout-grid-cell-spans_($span, $gutter);
89+
@include mdc-layout-grid-cell-span_($size, $default-span, $gutter);
10290
}
10391

10492
@mixin mdc-layout-grid-cell-order($order) {

packages/mdc-layout-grid/_variables.scss

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ $mdc-layout-grid-columns: (
2424
phone: 4
2525
) !default;
2626

27+
$mdc-layout-grid-default-margin: (
28+
desktop: 24px,
29+
tablet: 16px,
30+
phone: 16px
31+
) !default;
32+
33+
$mdc-layout-grid-default-gutter: (
34+
desktop: 24px,
35+
tablet: 16px,
36+
phone: 16px
37+
) !default;
38+
2739
$mdc-layout-grid-default-column-span: 4 !default;
28-
$mdc-layout-grid-default-margin: 16px !default;
29-
$mdc-layout-grid-default-gutter: 16px !default;
40+
41+
$mdc-layout-grid-max-width: null;

packages/mdc-layout-grid/mdc-layout-grid.scss

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,38 @@
1515
@import "./variables";
1616
@import "./mixins";
1717

18+
:root {
19+
@each $size in map-keys($mdc-layout-grid-columns) {
20+
--mdc-layout-grid-margin-#{$size}: map-get($mdc-layout-grid-default-margin, $size);
21+
--mdc-layout-grid-gutter-#{$size}: map-get($mdc-layout-grid-default-gutter, $size);
22+
}
23+
}
24+
1825
// postcss-bem-linter: define layout-grid
1926
.mdc-layout-grid {
20-
@include mdc-layout-grid($mdc-layout-grid-default-margin, $mdc-layout-grid-default-gutter);
27+
@each $size in map-keys($mdc-layout-grid-columns) {
28+
@include mdc-layout-grid-media-query_($size) {
29+
$margin: map-get($mdc-layout-grid-default-margin, $size);
30+
$gutter: map-get($mdc-layout-grid-default-gutter, $size);
31+
32+
@include mdc-layout-grid($size, $margin, $gutter, $mdc-layout-grid-max-width);
33+
}
34+
}
2135
}
2236

2337
.mdc-layout-grid__cell {
24-
@include mdc-layout-grid-cell($mdc-layout-grid-default-gutter);
25-
2638
@each $size in map-keys($mdc-layout-grid-columns) {
2739
@include mdc-layout-grid-media-query_($size) {
40+
$gutter: map-get($mdc-layout-grid-default-gutter, $size);
41+
42+
@include mdc-layout-grid-cell($size, $mdc-layout-grid-default-column-span, $gutter);
43+
2844
@for $span from 1 through map-get($mdc-layout-grid-columns, desktop) {
2945
// Span classes.
3046
// stylelint-disable max-nesting-depth
3147
@at-root .mdc-layout-grid__cell--span-#{$span},
3248
.mdc-layout-grid__cell--span-#{$span}-#{$size}.mdc-layout-grid__cell--span-#{$span}-#{$size} {
33-
@include mdc-layout-grid-cell-span_($size, $span, $mdc-layout-grid-default-gutter);
49+
@include mdc-layout-grid-cell-span_($size, $span, $gutter);
3450
}
3551
// stylelint-enable max-nesting-depth
3652
}

0 commit comments

Comments
 (0)