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

Commit 94d62ad

Browse files
authored
feat(layout-grid): Add fixed column width layout grid modifier. (#816)
Closes #748.
1 parent b67c3c2 commit 94d62ad

File tree

5 files changed

+151
-6
lines changed

5 files changed

+151
-6
lines changed

demos/layout-grid.html

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,46 @@
306306
</div>
307307
</div>
308308

309+
<div class="demo-grid-legend">Fixed column width layout grid</div>
310+
<div class="mdc-layout-grid">
311+
<div class="mdc-layout-grid__inner">
312+
<div class="mdc-layout-grid__cell">
313+
<div class="demo-controls">
314+
Desktop Column Width:
315+
<select id="desktop-column-width">
316+
<option value="72px" selected>72px</option>
317+
<option value="84px">84px</option>
318+
</select>
319+
</div>
320+
</div>
321+
<div class="mdc-layout-grid__cell">
322+
<div class="demo-controls">
323+
Tablet Column Width:
324+
<select id="tablet-column-width">
325+
<option value="72px" selected>72px</option>
326+
<option value="84px">84px</option>
327+
</select>
328+
</div>
329+
</div>
330+
<div class="mdc-layout-grid__cell">
331+
<div class="demo-controls">
332+
Phone Column Width:
333+
<select id="phone-column-width">
334+
<option value="72px" >72px</option>
335+
<option value="84px">84px</option>
336+
</select>
337+
</div>
338+
</div>
339+
</div>
340+
</div>
341+
<div class="demo-grid mdc-layout-grid mdc-layout-grid--fixed-column-width">
342+
<div class="mdc-layout-grid__inner">
343+
<div class="demo-cell mdc-layout-grid__cell mdc-layout-grid__cell--span-1"></div>
344+
<div class="demo-cell mdc-layout-grid__cell mdc-layout-grid__cell--span-1"></div>
345+
<div class="demo-cell mdc-layout-grid__cell mdc-layout-grid__cell--span-1"></div>
346+
</div>
347+
</div>
348+
309349
<div class="demo-ruler"><div id="current"></div></div>
310350
</section>
311351

@@ -323,6 +363,7 @@
323363
gutterSelectDesktop.addEventListener('change', function() {
324364
document.documentElement.style.setProperty('--mdc-layout-grid-gutter-desktop', gutterSelectDesktop.value);
325365
});
366+
326367
var marginSelectTablet = document.querySelector('#tablet-margin');
327368
marginSelectTablet.addEventListener('change', function() {
328369
document.documentElement.style.setProperty('--mdc-layout-grid-margin-tablet', marginSelectTablet.value);
@@ -332,6 +373,7 @@
332373
gutterSelectTablet.addEventListener('change', function() {
333374
document.documentElement.style.setProperty('--mdc-layout-grid-gutter-tablet', gutterSelectTablet.value);
334375
});
376+
335377
var marginSelectPhone = document.querySelector('#phone-margin');
336378
marginSelectPhone.addEventListener('change', function() {
337379
document.documentElement.style.setProperty('--mdc-layout-grid-margin-phone', marginSelectPhone.value);
@@ -342,6 +384,21 @@
342384
document.documentElement.style.setProperty('--mdc-layout-grid-gutter-phone', gutterSelectPhone.value);
343385
});
344386

387+
var columnWidthSelectDesktop = document.querySelector('#desktop-column-width');
388+
columnWidthSelectDesktop.addEventListener('change', function() {
389+
document.documentElement.style.setProperty('--mdc-layout-grid-column-width-desktop', columnWidthSelectDesktop.value);
390+
});
391+
392+
var columnWidthSelectTablet = document.querySelector('#tablet-column-width');
393+
columnWidthSelectTablet.addEventListener('change', function() {
394+
document.documentElement.style.setProperty('--mdc-layout-grid-column-width-tablet', columnWidthSelectTablet.value);
395+
});
396+
397+
var columnWidthSelectPhone = document.querySelector('#phone-column-width');
398+
columnWidthSelectPhone.addEventListener('change', function() {
399+
document.documentElement.style.setProperty('--mdc-layout-grid-column-width-phone', columnWidthSelectPhone.value);
400+
});
401+
345402
var current = document.querySelector('#current');
346403
var update = function() {
347404
var size = '(phone)';

packages/mdc-layout-grid/README.md

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,12 @@ npm install --save @material/layout-grid
4141

4242
## The layout grid
4343

44-
A grid consists of a group of cells, which get positioned in sequence according to a predefined number of columns.
45-
Cells specify how many columns to span (the default being 4), and get placed side by side while there is room. When
46-
there isn't enough room for a cell, it gets moved to the beginning of the next row, and placement continues as usual.
44+
A grid is a container that consists of a group of cells. Grid can define its own max-width or designate its columns to be a certain width. Cells get positioned in sequence according to a predefined number of columns.
4745

4846
The grid has 12 columns in desktop mode (>= 840px), 8 columns in tablet mode (>= 480px), and 4 columns in phone mode
49-
(< 480px). Column widths are variable; margins and gutters are fixed, with columns taking up the remainder of the space.
47+
(< 480px). Cells specify how many columns to span (the default is 4). Cells are placed side by side until there is no more room, then the next cell is placed at the beginning of the next row.
5048

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.
49+
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. The columns are evenly distributed within the container width, minus the width of all margins and gutters. Layout grids set default margins and gutters to 24px on desktop, 16px on tablet and phone, according to the Material Design spec.
5250

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

@@ -67,6 +65,8 @@ The grid and cells are not styled in any way, serving only for alignment and pos
6765

6866
The grid should have the `mdc-layout-grid` class. Every cell should have the `mdc-layout-grid__cell` class and must be wrapped by `mdc-layout-grid__inner` for proper alignment. Behavior for grids containing direct children without the `mdc-layout-grid__cell` class is undefined.
6967

68+
By default, `mdc-layout-grid` behaves like a fluid container, which takes up its parents container's available space. You can change the behavior using [max-width](#max-width) or [fixed column width layout grid](#fixed-column-width-grid).
69+
7070

7171
### Margins and gutters
7272

@@ -137,6 +137,26 @@ columns wide.
137137
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.
138138

139139

140+
### Fixed column width grid
141+
142+
You can designate each column to have a certain width by using `mdc-layout-grid--fixed-column-width` modifier. The column width can be specified through sass map `$mdc-layout-grid-column-width` or css custom properties `--mdc-layout-grid-column-width-{screen_size}`. The column width is set to 72px on all devices by default.
143+
144+
```
145+
<style>
146+
:root {
147+
--mdc-layout-grid-column-width-desktop: 84px;
148+
}
149+
</style>
150+
151+
<div class="mdc-layout-grid mdc-layout-grid--fixed-column-width">
152+
<div class="mdc-layout-grid__inner">
153+
<div class="mdc-layout-grid__cell"></div>
154+
<div class="mdc-layout-grid__cell"></div>
155+
</div>
156+
</div>
157+
```
158+
159+
140160
### Nested grid
141161

142162
When your contents need extra structure that cannot be supported by single layout grid, you can nest layout grid within each other. To nest layout grid, add a new `mdc-layout-grid__inner` to wrap around nested `mdc-layout-grid__cell` within an existing `mdc-layout-grid__cell`.
@@ -160,7 +180,6 @@ However, Material guideline do not recommend have a deeply nested grid since it
160180
</div>
161181
```
162182

163-
164183
### Reordering
165184

166185
By default, items are positioned in the source order. However, you can reorder them by using the
@@ -235,6 +254,18 @@ behavior by using one of the `mdc-layout-grid__cell--align-{position}` alignment
235254

236255
> 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).
237256
257+
### mdc-layout-grid-fixed-column-width
258+
259+
```scss
260+
@include mdc-layout-grid-fixed-column-width(desktop, 24px, 24px, 72px);
261+
```
262+
263+
`mdc-layout-grid-fixed-column-width` defines the container by width designated column width. The mixin takes four parameters:
264+
- `$size`: the target platform: `desktop`, `tablet` or `phone`.
265+
- `$margin`: the size of the grid margin.
266+
- `$gutter`: the size of the gutter between cells.
267+
- `$column-width`: the width of the column within the grid.
268+
238269

239270
### mdc-layout-grid-cell-order
240271

packages/mdc-layout-grid/_mixins.scss

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
// Private mixins, meant for internal use.
1616
@mixin mdc-layout-grid-media-query_($size) {
17+
@if not map-has-key($mdc-layout-grid-columns, $size) {
18+
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
19+
}
20+
1721
@if $size == phone {
1822
// Phone
1923
@media (max-width: map-get($mdc-layout-grid-breakpoints, tablet) - 1px) {
@@ -37,6 +41,10 @@
3741
}
3842

3943
@mixin mdc-layout-grid-cell-span_($size, $span, $gutter) {
44+
@if not map-has-key($mdc-layout-grid-columns, $size) {
45+
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
46+
}
47+
4048
$percent: percentage($span / map-get($mdc-layout-grid-columns, $size));
4149

4250
@if $percent > 100% {
@@ -54,6 +62,10 @@
5462

5563
// Public mixins, meant for developer usage.
5664
@mixin mdc-layout-grid($size, $margin, $max-width: null) {
65+
@if not map-has-key($mdc-layout-grid-columns, $size) {
66+
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
67+
}
68+
5769
box-sizing: border-box;
5870
margin: 0 auto;
5971

@@ -66,6 +78,10 @@
6678
}
6779

6880
@mixin mdc-layout-grid-inner($size, $margin, $gutter) {
81+
@if not map-has-key($mdc-layout-grid-columns, $size) {
82+
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
83+
}
84+
6985
display: flex;
7086
flex-flow: row wrap;
7187
align-items: stretch;
@@ -82,6 +98,10 @@
8298
}
8399

84100
@mixin mdc-layout-grid-cell($size, $default-span, $gutter) {
101+
@if not map-has-key($mdc-layout-grid-columns, $size) {
102+
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
103+
}
104+
85105
box-sizing: border-box;
86106
margin: $gutter / 2;
87107
margin: calc(var(--mdc-layout-grid-gutter-#{$size}, #{$gutter}) / 2);
@@ -122,3 +142,21 @@
122142
align-self: stretch;
123143
}
124144
}
145+
146+
@mixin mdc-layout-grid-fixed-column-width($size, $margin, $gutter, $column-width) {
147+
@if not map-has-key($mdc-layout-grid-columns, $size) {
148+
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
149+
}
150+
151+
$columnCount: map-get($mdc-layout-grid-columns, $size);
152+
$gutter-number: $columnCount - 1;
153+
$margin-number: 2;
154+
155+
width: $column-width * $columnCount + $gutter * $gutter-number + $margin * $margin-number;
156+
width:
157+
calc(
158+
var(--mdc-layout-grid-column-width-#{$size}, #{$column-width}) * #{$columnCount} +
159+
var(--mdc-layout-grid-gutter-#{$size}, #{$gutter}) * #{$gutter-number} +
160+
var(--mdc-layout-grid-margin-#{$size}, #{$margin}) * #{$margin-number}
161+
);
162+
}

packages/mdc-layout-grid/_variables.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ $mdc-layout-grid-default-gutter: (
3636
phone: 16px
3737
) !default;
3838

39+
$mdc-layout-grid-column-width: (
40+
desktop: 72px,
41+
tablet: 72px,
42+
phone: 72px
43+
) !default;
44+
3945
$mdc-layout-grid-default-column-span: 4 !default;
4046

4147
$mdc-layout-grid-max-width: null;

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
@each $size in map-keys($mdc-layout-grid-columns) {
2020
--mdc-layout-grid-margin-#{$size}: map-get($mdc-layout-grid-default-margin, $size);
2121
--mdc-layout-grid-gutter-#{$size}: map-get($mdc-layout-grid-default-gutter, $size);
22+
--mdc-layout-grid-column-width-#{$size}: map-get($mdc-layout-grid-column-width, $size);
2223
}
2324
}
2425

@@ -84,4 +85,16 @@
8485
}
8586
}
8687

88+
.mdc-layout-grid--fixed-column-width {
89+
@each $size in map-keys($mdc-layout-grid-columns) {
90+
@include mdc-layout-grid-media-query_($size) {
91+
$margin: map-get($mdc-layout-grid-default-margin, $size);
92+
$gutter: map-get($mdc-layout-grid-default-gutter, $size);
93+
$column-width: map-get($mdc-layout-grid-column-width, $size);
94+
95+
@include mdc-layout-grid-fixed-column-width($size, $margin, $gutter, $column-width);
96+
}
97+
}
98+
}
99+
87100
// postcss-bem-linter: end

0 commit comments

Comments
 (0)