Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(layout-grid): Add fixed column width layout grid modifier. #816

Merged
merged 1 commit into from
Jun 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions demos/layout-grid.html
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,46 @@
</div>
</div>

<div class="demo-grid-legend">Fixed column width layout grid</div>
<div class="mdc-layout-grid">
<div class="mdc-layout-grid__inner">
<div class="mdc-layout-grid__cell">
<div class="demo-controls">
Desktop Column Width:
<select id="desktop-column-width">
<option value="72px" selected>72px</option>
<option value="84px">84px</option>
</select>
</div>
</div>
<div class="mdc-layout-grid__cell">
<div class="demo-controls">
Tablet Column Width:
<select id="tablet-column-width">
<option value="72px" selected>72px</option>
<option value="84px">84px</option>
</select>
</div>
</div>
<div class="mdc-layout-grid__cell">
<div class="demo-controls">
Phone Column Width:
<select id="phone-column-width">
<option value="72px" >72px</option>
<option value="84px">84px</option>
</select>
</div>
</div>
</div>
</div>
<div class="demo-grid mdc-layout-grid mdc-layout-grid--fixed-column-width">
<div class="mdc-layout-grid__inner">
<div class="demo-cell mdc-layout-grid__cell mdc-layout-grid__cell--span-1"></div>
<div class="demo-cell mdc-layout-grid__cell mdc-layout-grid__cell--span-1"></div>
<div class="demo-cell mdc-layout-grid__cell mdc-layout-grid__cell--span-1"></div>
</div>
</div>

<div class="demo-ruler"><div id="current"></div></div>
</section>

Expand All @@ -323,6 +363,7 @@
gutterSelectDesktop.addEventListener('change', function() {
document.documentElement.style.setProperty('--mdc-layout-grid-gutter-desktop', gutterSelectDesktop.value);
});

var marginSelectTablet = document.querySelector('#tablet-margin');
marginSelectTablet.addEventListener('change', function() {
document.documentElement.style.setProperty('--mdc-layout-grid-margin-tablet', marginSelectTablet.value);
Expand All @@ -332,6 +373,7 @@
gutterSelectTablet.addEventListener('change', function() {
document.documentElement.style.setProperty('--mdc-layout-grid-gutter-tablet', gutterSelectTablet.value);
});

var marginSelectPhone = document.querySelector('#phone-margin');
marginSelectPhone.addEventListener('change', function() {
document.documentElement.style.setProperty('--mdc-layout-grid-margin-phone', marginSelectPhone.value);
Expand All @@ -342,6 +384,21 @@
document.documentElement.style.setProperty('--mdc-layout-grid-gutter-phone', gutterSelectPhone.value);
});

var columnWidthSelectDesktop = document.querySelector('#desktop-column-width');
columnWidthSelectDesktop.addEventListener('change', function() {
document.documentElement.style.setProperty('--mdc-layout-grid-column-width-desktop', columnWidthSelectDesktop.value);
});

var columnWidthSelectTablet = document.querySelector('#tablet-column-width');
columnWidthSelectTablet.addEventListener('change', function() {
document.documentElement.style.setProperty('--mdc-layout-grid-column-width-tablet', columnWidthSelectTablet.value);
});

var columnWidthSelectPhone = document.querySelector('#phone-column-width');
columnWidthSelectPhone.addEventListener('change', function() {
document.documentElement.style.setProperty('--mdc-layout-grid-column-width-phone', columnWidthSelectPhone.value);
});

var current = document.querySelector('#current');
var update = function() {
var size = '(phone)';
Expand Down
43 changes: 37 additions & 6 deletions packages/mdc-layout-grid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,12 @@ npm install --save @material/layout-grid

## The layout grid

A grid consists of a group of cells, which get positioned in sequence according to a predefined number of columns.
Cells specify how many columns to span (the default being 4), and get placed side by side while there is room. When
there isn't enough room for a cell, it gets moved to the beginning of the next row, and placement continues as usual.
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.

The grid has 12 columns in desktop mode (>= 840px), 8 columns in tablet mode (>= 480px), and 4 columns in phone mode
(< 480px). Column widths are variable; margins and gutters are fixed, with columns taking up the remainder of the space.
(< 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.

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.
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.

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

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

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.

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).


### Margins and gutters

Expand Down Expand Up @@ -137,6 +137,26 @@ columns wide.
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.


### Fixed column width grid

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.

```
<style>
:root {
--mdc-layout-grid-column-width-desktop: 84px;
}
</style>

<div class="mdc-layout-grid mdc-layout-grid--fixed-column-width">
<div class="mdc-layout-grid__inner">
<div class="mdc-layout-grid__cell"></div>
<div class="mdc-layout-grid__cell"></div>
</div>
</div>
```


### Nested grid

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`.
Expand All @@ -160,7 +180,6 @@ However, Material guideline do not recommend have a deeply nested grid since it
</div>
```


### Reordering

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

> 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).

### mdc-layout-grid-fixed-column-width

```scss
@include mdc-layout-grid-fixed-column-width(desktop, 24px, 24px, 72px);
```

`mdc-layout-grid-fixed-column-width` defines the container by width designated column width. The mixin takes four parameters:
- `$size`: the target platform: `desktop`, `tablet` or `phone`.
- `$margin`: the size of the grid margin.
- `$gutter`: the size of the gutter between cells.
- `$column-width`: the width of the column within the grid.


### mdc-layout-grid-cell-order

Expand Down
38 changes: 38 additions & 0 deletions packages/mdc-layout-grid/_mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

// Private mixins, meant for internal use.
@mixin mdc-layout-grid-media-query_($size) {
@if not map-has-key($mdc-layout-grid-columns, $size) {
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
}

@if $size == phone {
// Phone
@media (max-width: map-get($mdc-layout-grid-breakpoints, tablet) - 1px) {
Expand All @@ -37,6 +41,10 @@
}

@mixin mdc-layout-grid-cell-span_($size, $span, $gutter) {
@if not map-has-key($mdc-layout-grid-columns, $size) {
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
}

$percent: percentage($span / map-get($mdc-layout-grid-columns, $size));

@if $percent > 100% {
Expand All @@ -54,6 +62,10 @@

// Public mixins, meant for developer usage.
@mixin mdc-layout-grid($size, $margin, $max-width: null) {
@if not map-has-key($mdc-layout-grid-columns, $size) {
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
}

box-sizing: border-box;
margin: 0 auto;

Expand All @@ -66,6 +78,10 @@
}

@mixin mdc-layout-grid-inner($size, $margin, $gutter) {
@if not map-has-key($mdc-layout-grid-columns, $size) {
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
}

display: flex;
flex-flow: row wrap;
align-items: stretch;
Expand All @@ -82,6 +98,10 @@
}

@mixin mdc-layout-grid-cell($size, $default-span, $gutter) {
@if not map-has-key($mdc-layout-grid-columns, $size) {
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
}

box-sizing: border-box;
margin: $gutter / 2;
margin: calc(var(--mdc-layout-grid-gutter-#{$size}, #{$gutter}) / 2);
Expand Down Expand Up @@ -122,3 +142,21 @@
align-self: stretch;
}
}

@mixin mdc-layout-grid-fixed-column-width($size, $margin, $gutter, $column-width) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$size is kinda a vague variable...can it be $platform-type?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also add the same error handling in the sass as we do in mdc-theme? e.g.:

  @if not map-has-key($mdc-layout-grid-columns, $size) {
    @error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
  }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel the original code meant screen-size and I don't think it is vague. Since we both documented that clearly and do the type check, I feel fine to leave just as it is. WDYT?

@if not map-has-key($mdc-layout-grid-columns, $size) {
@error "Invalid style specified! Choose one of #{map-keys($mdc-layout-grid-columns)}";
}

$columnCount: map-get($mdc-layout-grid-columns, $size);
$gutter-number: $columnCount - 1;
$margin-number: 2;

width: $column-width * $columnCount + $gutter * $gutter-number + $margin * $margin-number;
width:
calc(
var(--mdc-layout-grid-column-width-#{$size}, #{$column-width}) * #{$columnCount} +
var(--mdc-layout-grid-gutter-#{$size}, #{$gutter}) * #{$gutter-number} +
var(--mdc-layout-grid-margin-#{$size}, #{$margin}) * #{$margin-number}
);
}
6 changes: 6 additions & 0 deletions packages/mdc-layout-grid/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ $mdc-layout-grid-default-gutter: (
phone: 16px
) !default;

$mdc-layout-grid-column-width: (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe $mdc-layout-grid-platform-column-widths? It more closely follows the naming conventions of this pattern in other components.

It would obviously have to be changed in _mixins.scss as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to look up for this pattern but haven't seen any one have this pattern 😞 The thing I search and found that use sass map to define different property based on screen size only appears in mdc-layout-grid.

Not sure if I misunderstand what you meant here, could you elaborate a bit?

desktop: 72px,
tablet: 72px,
phone: 72px
) !default;

$mdc-layout-grid-default-column-span: 4 !default;

$mdc-layout-grid-max-width: null;
13 changes: 13 additions & 0 deletions packages/mdc-layout-grid/mdc-layout-grid.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
@each $size in map-keys($mdc-layout-grid-columns) {
--mdc-layout-grid-margin-#{$size}: map-get($mdc-layout-grid-default-margin, $size);
--mdc-layout-grid-gutter-#{$size}: map-get($mdc-layout-grid-default-gutter, $size);
--mdc-layout-grid-column-width-#{$size}: map-get($mdc-layout-grid-column-width, $size);
}
}

Expand Down Expand Up @@ -84,4 +85,16 @@
}
}

.mdc-layout-grid--fixed-column-width {
@each $size in map-keys($mdc-layout-grid-columns) {
@include mdc-layout-grid-media-query_($size) {
$margin: map-get($mdc-layout-grid-default-margin, $size);
$gutter: map-get($mdc-layout-grid-default-gutter, $size);
$column-width: map-get($mdc-layout-grid-column-width, $size);

@include mdc-layout-grid-fixed-column-width($size, $margin, $gutter, $column-width);
}
}
}

// postcss-bem-linter: end