Skip to content

Commit 6ceec7a

Browse files
feat(grid): improve grid to a column layout with more flexibility (#10485)
The old grid is still supported but will be deprecated in the future. closes #6050 closes #7508
1 parent 43b9097 commit 6ceec7a

File tree

13 files changed

+1772
-229
lines changed

13 files changed

+1772
-229
lines changed

src/components/grid/col.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Directive } from '@angular/core';
2+
3+
/**
4+
* @name Col
5+
* @module ionic
6+
* @description
7+
*
8+
* Column description
9+
*
10+
* ## Column attributes
11+
*
12+
* By default, columns will stretch to fill the entire height of the row.
13+
* There are several attributes that can be added to a column to customize this behavior.
14+
*
15+
* | Property | Description |
16+
* |-----------------------|-------------------------------------------------------------------------------------------------------------|
17+
* | align-self-start | Adds `align-self: flex-start`. The column will be vertically aligned at the top. |
18+
* | align-self-center | Adds `align-self: center`. The column will be vertically aligned in the center. |
19+
* | align-self-end | Adds `align-self: flex-end`. The column will be vertically aligned at the bottom. |
20+
* | align-self-stretch | Adds `align-self: stretch`. The column will be stretched to take up the entire height of the row. |
21+
* | align-self-baseline | Adds `align-self: baseline`. The column will be vertically aligned at its baselines. |
22+
*
23+
*
24+
*/
25+
@Directive({
26+
selector: 'ion-col, [ion-col]',
27+
host: {
28+
'class': 'col'
29+
}
30+
})
31+
export class Col {
32+
33+
}

src/components/grid/grid.mixins.scss

Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
@import "../../themes/ionic.globals";
2+
3+
// Responsive Mixins
4+
// --------------------------------------------------
5+
6+
// Creates a grid with padding
7+
// ---------------------------------------------------------------------------------
8+
9+
@mixin make-grid($padding-width: $grid-padding-width) {
10+
padding: $padding-width / 2;
11+
margin-left: auto;
12+
margin-right: auto;
13+
width: 100%;
14+
15+
// Remove the padding from the grid and all immediate children columns
16+
&[no-padding] {
17+
padding: 0;
18+
19+
> .row > .col {
20+
padding: 0;
21+
}
22+
}
23+
}
24+
25+
// Creates maximum widths for the grid based on screen size
26+
// ---------------------------------------------------------------------------------
27+
28+
@mixin make-grid-max-widths($max-widths: $grid-max-widths, $breakpoints: $grid-breakpoints) {
29+
@each $breakpoint, $container-max-width in $max-widths {
30+
@include media-breakpoint-up($breakpoint, $breakpoints) {
31+
width: $container-max-width;
32+
max-width: 100%;
33+
}
34+
}
35+
}
36+
37+
// Creates a row used to align columns
38+
// ---------------------------------------------------------------------------------
39+
40+
@mixin make-row() {
41+
display: flex;
42+
flex-wrap: wrap;
43+
44+
&[nowrap] {
45+
flex-wrap: nowrap;
46+
}
47+
48+
&[wrap-reverse] {
49+
flex-wrap: wrap-reverse;
50+
}
51+
52+
&[align-items-start] {
53+
align-items: flex-start;
54+
}
55+
56+
&[align-items-center] {
57+
align-items: center;
58+
}
59+
60+
&[align-items-end] {
61+
align-items: flex-end;
62+
}
63+
64+
&[align-items-stretch] {
65+
align-items: stretch;
66+
}
67+
68+
&[align-items-baseline] {
69+
align-items: baseline;
70+
}
71+
72+
&[justify-content-start] {
73+
justify-content: flex-start;
74+
}
75+
76+
&[justify-content-center] {
77+
justify-content: center;
78+
}
79+
80+
&[justify-content-end] {
81+
justify-content: flex-end;
82+
}
83+
84+
&[justify-content-around] {
85+
justify-content: space-around;
86+
}
87+
88+
&[justify-content-between] {
89+
justify-content: space-between;
90+
}
91+
}
92+
93+
94+
// Creates the base column which has shared styles among all columns
95+
// ---------------------------------------------------------------------------------
96+
97+
@mixin make-column-base($padding-width: $grid-padding-width) {
98+
position: relative;
99+
100+
padding: $padding-width / 2;
101+
102+
width: 100%;
103+
margin: 0;
104+
min-height: 1px; // Prevent columns from collapsing when empty
105+
flex-basis: 0;
106+
flex-grow: 1;
107+
max-width: 100%;
108+
109+
&[align-self-start] {
110+
align-self: flex-start;
111+
}
112+
113+
&[align-self-end] {
114+
align-self: flex-end;
115+
}
116+
117+
&[align-self-center] {
118+
align-self: center;
119+
}
120+
121+
&[align-self-stretch] {
122+
align-self: stretch;
123+
}
124+
125+
&[align-self-baseline] {
126+
align-self: baseline;
127+
}
128+
}
129+
130+
131+
// Create an individual column
132+
// ---------------------------------------------------------------------------------
133+
134+
@mixin make-column($size, $columns: $grid-columns) {
135+
flex: 0 0 percentage($size / $columns);
136+
width: percentage($size / $columns);
137+
// Add a `max-width` to ensure content within each column does not blow out
138+
// the width of the column. Applies to IE10+ and Firefox. Chrome and Safari
139+
// do not appear to require this.
140+
max-width: percentage($size / $columns);
141+
}
142+
143+
144+
// Adds padding to the column
145+
// ---------------------------------------------------------------------------------
146+
147+
@mixin make-column-padding($padding-widths: $grid-padding-widths) {
148+
@each $breakpoint in map-keys($padding-widths) {
149+
@include media-breakpoint-up($breakpoint) {
150+
$padding-width: map-get($padding-widths, $breakpoint);
151+
padding: ($padding-width / 2);
152+
}
153+
}
154+
}
155+
156+
157+
// Offset the column using margin-left
158+
// ---------------------------------------------------------------------------------
159+
160+
@mixin make-column-offset($size, $columns: $grid-columns) {
161+
margin-left: percentage($size / $columns);
162+
}
163+
164+
165+
// Push the column using left
166+
// ---------------------------------------------------------------------------------
167+
168+
@mixin make-column-push($size, $columns: $grid-columns) {
169+
left: if($size > 0, percentage($size / $columns), auto);
170+
}
171+
172+
173+
// Pull the column using right
174+
// ---------------------------------------------------------------------------------
175+
176+
@mixin make-column-pull($size, $columns: $grid-columns) {
177+
right: if($size > 0, percentage($size / $columns), auto);
178+
}
179+
180+
181+
// Determine which modifier to add
182+
// ---------------------------------------------------------------------------------
183+
184+
@mixin make-column-modifier($type, $size, $columns) {
185+
// Work around the lack of dynamic mixin @include support (https://github.com/sass/sass/issues/626)
186+
@if $type == push {
187+
@include make-column-push($size, $columns);
188+
} @else if $type == pull {
189+
@include make-column-pull($size, $columns);
190+
} @else if $type == offset {
191+
@include make-column-offset($size, $columns);
192+
}
193+
}
194+
195+
196+
// Create the responsive grid columns
197+
// --------------------------------------------------
198+
199+
@mixin make-grid-columns($columns: $grid-columns, $padding-widths: $grid-padding-widths, $breakpoints: $grid-breakpoints) {
200+
@each $breakpoint in map-keys($breakpoints) {
201+
$infix: breakpoint-infix($breakpoint, $breakpoints);
202+
203+
// Allow columns to stretch full width below their breakpoints
204+
@for $i from 1 through $columns {
205+
[col#{$infix}-#{$i}] {
206+
@include make-column-padding($padding-widths);
207+
}
208+
}
209+
210+
[col#{$infix}] {
211+
@include make-column-padding($padding-widths);
212+
}
213+
214+
@include media-breakpoint-up($breakpoint, $breakpoints) {
215+
// Provide basic `[col-{bp}]` attributes for equal-width flexbox columns
216+
[col#{$infix}] {
217+
flex-basis: 0;
218+
flex-grow: 1;
219+
220+
max-width: 100%;
221+
}
222+
223+
[col#{$infix}-auto] {
224+
flex: 0 0 auto;
225+
226+
width: auto;
227+
}
228+
229+
@for $i from 1 through $columns {
230+
[col#{$infix}-#{$i}] {
231+
@include make-column($i, $columns);
232+
}
233+
}
234+
235+
@each $modifier in (pull, push) {
236+
@for $i from 0 through $columns {
237+
[#{$modifier}#{$infix}-#{$i}] {
238+
@include make-column-modifier($modifier, $i, $columns)
239+
}
240+
}
241+
}
242+
243+
// `$columns - 1` because offsetting by the width of an entire row isn't possible
244+
@for $i from 0 through ($columns - 1) {
245+
@if not ($infix == "" and $i == 0) { // Avoid emitting useless [offset-xs-0]
246+
[offset#{$infix}-#{$i}] {
247+
@include make-column-modifier(offset, $i, $columns)
248+
}
249+
}
250+
}
251+
}
252+
}
253+
}
254+
255+
256+
// Breakpoint Mixins
257+
// ---------------------------------------------------------------------------------
258+
259+
// Breakpoint viewport sizes and media queries.
260+
//
261+
// Breakpoints are defined as a map of (name: minimum width), order from small to large:
262+
//
263+
// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)
264+
//
265+
// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
266+
267+
// ---------------------------------------------------------------------------------
268+
269+
// Minimum breakpoint width. Null for the smallest (first) breakpoint.
270+
//
271+
// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
272+
// 576px
273+
@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
274+
$min: map-get($breakpoints, $name);
275+
@return if($min != 0, $min, null);
276+
}
277+
278+
279+
// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront.
280+
// Useful for making responsive utilities.
281+
//
282+
// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
283+
// "" (Returns a blank string)
284+
// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
285+
// "-sm"
286+
@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
287+
@return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
288+
}
289+
290+
291+
// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
292+
// Makes the @content apply to the given breakpoint and wider.
293+
@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
294+
$min: breakpoint-min($name, $breakpoints);
295+
@if $min {
296+
@media (min-width: $min) {
297+
@content;
298+
}
299+
} @else {
300+
@content;
301+
}
302+
}

0 commit comments

Comments
 (0)