├── .gitignore
├── .npmignore
├── LICENSE.md
├── README.md
├── examples
├── bootstrap
│ ├── README.md
│ ├── css-gridish.json
│ ├── css-gridish
│ │ ├── README.md
│ │ ├── bootstrap-grid.sketch
│ │ ├── css
│ │ │ ├── bootstrap-grid-legacy.css
│ │ │ ├── bootstrap-grid-legacy.min.css
│ │ │ ├── bootstrap-grid.css
│ │ │ └── bootstrap-grid.min.css
│ │ └── scss
│ │ │ ├── _core.scss
│ │ │ ├── _functions.scss
│ │ │ ├── _mixins.scss
│ │ │ ├── _sass-list-maps.scss
│ │ │ ├── _utilities.scss
│ │ │ ├── _values.scss
│ │ │ ├── _variables.scss
│ │ │ ├── bootstrap-grid-legacy.scss
│ │ │ └── bootstrap-grid.scss
│ ├── index.html
│ ├── intro.md
│ ├── package.json
│ └── yarn.lock
├── carbon
│ ├── README.md
│ ├── css-gridish.json
│ ├── css-gridish
│ │ ├── README.md
│ │ ├── bx-grid.sketch
│ │ ├── css
│ │ │ ├── bx-grid-legacy.css
│ │ │ ├── bx-grid-legacy.min.css
│ │ │ ├── bx-grid.css
│ │ │ └── bx-grid.min.css
│ │ └── scss
│ │ │ ├── _core.scss
│ │ │ ├── _functions.scss
│ │ │ ├── _mixins.scss
│ │ │ ├── _sass-list-maps.scss
│ │ │ ├── _utilities.scss
│ │ │ ├── _values.scss
│ │ │ ├── _variables.scss
│ │ │ ├── bx-grid-legacy.scss
│ │ │ └── bx-grid.scss
│ ├── index.html
│ ├── intro.md
│ ├── package.json
│ └── yarn.lock
└── material
│ ├── README.md
│ ├── css-gridish.json
│ ├── css-gridish
│ ├── README.md
│ ├── css
│ │ ├── material-grid-legacy.css
│ │ ├── material-grid-legacy.min.css
│ │ ├── material-grid.css
│ │ └── material-grid.min.css
│ ├── material-grid.sketch
│ └── scss
│ │ ├── _core.scss
│ │ ├── _functions.scss
│ │ ├── _mixins.scss
│ │ ├── _sass-list-maps.scss
│ │ ├── _utilities.scss
│ │ ├── _values.scss
│ │ ├── _variables.scss
│ │ ├── material-grid-legacy.scss
│ │ └── material-grid.scss
│ ├── example.html
│ ├── index.html
│ ├── intro.md
│ ├── package.json
│ └── yarn.lock
├── extension
├── LICENSE.md
├── icons
│ ├── icon128.png
│ ├── icon16.png
│ ├── icon19.png
│ ├── icon32.png
│ ├── icon48.png
│ └── icon64.png
├── manifest.json
└── src
│ ├── browserAction
│ ├── browserAction.html
│ └── browserAction.js
│ └── inject
│ ├── inject.css
│ └── inject.js
├── graphics
├── configDiagram.png
├── graphics.sketch
├── gridish.png
└── gridish_3times.gif
├── gulpfile.js
├── index.html
├── package.json
├── src
├── docs
│ └── README.md.hbs
├── index.js
├── scss
│ ├── _core.scss
│ ├── _functions.scss
│ ├── _mixins.scss
│ ├── _sass-list-maps.scss
│ ├── _utilities.scss
│ ├── _variables.scss
│ ├── gridish-grid-legacy.scss
│ └── gridish-grid.scss
└── sketch
│ ├── artboard.json
│ └── files
│ ├── document.json
│ ├── meta.json
│ ├── pages
│ └── BC333699-815E-4E1B-9816-9836EDA5B291.json
│ ├── previews
│ └── preview.png
│ └── user.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | bin
2 | etc
3 | node_modules
4 | output
5 | *.log
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | examples
2 | extension
3 | graphics
4 | output
5 | src
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2017 IBM
2 | Licensed under the Apache License, Version 2.0 (the "License");
3 | you may not use this file except in compliance with the License.
4 | You may obtain a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS,
10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | See the License for the specific language governing permissions and
12 | limitations under the License.
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CSS Gridish
2 |
3 | 
4 |
5 | CSS Gridish takes design specs of your product’s grid and builds out several resources for your team to use:
6 |
7 | * Sketch file with artboards and grid/layout settings for designers
8 | * CSS/SCSS code using CSS Grid with a CSS Flexbox fallback for developers
9 | * [Google Chrome extension](https://chrome.google.com/webstore/detail/css-gridish/ebhcneoilkamaddhlphlehojpcooobgc) for anyone to check a webpage’s alignment
10 |
11 | **This tool is not a grid system with a grid already designed for you.** Instead, CSS Gridish builds all of the resources for the grid your team designed.
12 |
13 | We hope it helps teams adapt CSS Grid sooner and enables more complex layouts. To show how versatile the tool is, we have examples of grids from [Bootstrap,](https://ibm.github.io/css-gridish/examples/bootstrap/index.html) [Carbon Design System,](https://ibm.github.io/css-gridish/examples/carbon/index.html) and [Material Design.](https://ibm.github.io/css-gridish/examples/material/index.html)
14 |
15 | The truth is that many enterprise projects can’t afford to drop support for browsers that do not [support CSS Grid Layout](https://developer.mozilla.org/en-US/docs/Web/CSS/grid#Browser_compatibility) yet. This tool takes your grid’s design specs and builds a slim CSS Grid Layout implementation and a fallback to [CSS Flexbox support.](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout#Browser_compatibility)
16 |
17 | ## Build your grid code
18 |
19 | Requires [Node v8.2.0](https://nodejs.org/en/) or higher, which includes npm and npx.
20 |
21 | 1. Create a file called `css-gridish.json` in your project root. See the [config documentation](#config-file) or an [example config](./examples/material/css-gridish.json) for help.
22 | 2. Determine how you want your grid built:
23 | * If you want to build once, run command `npx css-gridish`.
24 | * If you want to add the grid building to your project’s build process:
25 | 1. Run command `npm install css-gridish`.
26 | 2. Add `scripts: {build: "css-gridish"}` in your `package.json`.
27 | 3. Run command `npm run build`.
28 |
29 | Your CSS and `README.md` with class documentation will be built into `./css-gridish/`.
30 |
31 | ### Config file
32 |
33 | 
34 |
35 | The config file is where all of your design system specs live. See this [example](./examples/carbon/css-gridish.json) for help. Edit your `css-gridish.json` to have all generated grid content match your design system:
36 |
37 | ```
38 | {
39 | "prefix": "gridish", // Custom prefix for all classes and filenames
40 | "breakpoints": {
41 | // Class name for a breakpoint
42 | "sm": {
43 | "breakpoint": 20, // Min-width for media query (number in rem)
44 | "columns": 4, // Quantity of columns (number)
45 | "gutter": "2rem", // Space between columns (rem string, px string, vw string or 0)
46 | "margin": "3vw" // Horizontal margin of grid container (rem string, px string, vw string or 0)
47 | },
48 | ...
49 | "max": {
50 | "breakpoint": 100,
51 | "columns": 12,
52 | "gutter": "4rem",
53 | "margin": "5vw"
54 | }
55 | },
56 | "extraArtboards": {
57 | "xlg": 100 // Additional breakpoint for the Sketch file (number in rem)
58 | },
59 | "rem": 16, // Base rem unit for all measurements (number in px)
60 | "rowHeight": 0.5, // Height of a fixed row (number in rem)
61 | "rows": 30, // Quantity of row variables (number)
62 | "paths": {
63 | "route": "css-gridish", // Route that files save in from project root (optional, use `""` for project root, `"css-gridish"` is default)
64 | "intro": "intro.md" // Path to any markdown you want inserted at the top of your README.md documentation (optional)
65 | }
66 | }
67 | ```
68 |
69 | **Tip:** For the best results in Sketch, we recommend you make your grid breakpoints, margin, and gutter divisible by the row height.
70 |
71 | **Required:** Even if your design specs do not change between breakpoints, you need to list the max-width breakpoint in the `breakpoints` object.
72 |
73 | The first breakpoint min-width media query is not used to save kilobytes, but we recommend stating it anyways for future artboard-making tools.
74 |
75 | ## Legacy support
76 |
77 | If you are supporting browsers that lack [CSS Grid Layout support](https://developer.mozilla.org/en-US/docs/Web/CSS/grid#Browser_compatibility), you can use `css-gridish/yourPrefix-legacy.min.css` and the legacy classes detailed in the `README.md`. With the legacy file and classes, the browsers that do not support the final CSS Grid Legacy spec will fallback to a CSS Flexbox alternative. The CSS Flexbox alternative supports embedded subgrids that still reflect the overall grid system’s column structure.
78 |
79 | ### User-defined breakpoints
80 |
81 | One of the best parts about CSS Grid Layout is that your users can rearrange the layout at any width in their own media query. Your grid will also support rearranging layout at custom breakpoints for the legacy implementation when the user compiles their own Sass. Just have them define the following map of rem widths before they import in your Sass file:
82 |
83 | ```scss
84 | $extraBreakpoints: (
85 | xsm: 10,
86 | whatever: 78,
87 | superxlarge: 1000,
88 | ...
89 | );
90 | @import './css-gridish/scss/yourPrefix-legacy.scss;
91 | ```
92 |
93 | ### Transitioning from Legacy
94 |
95 | Once your experience can drop support for browsers like IE 11 and Edge <15, you can simply remove all legacy classes and switch over to the non-legacy files. This is a great progressive-enhancement for your performance when it happens.
96 |
97 | ## Future Updates
98 |
99 | * [ ] Once Edge and Safari gain `display: subgrid` support, we can remove our dependence on `vw` units.
100 | * [ ] Once a solution in the CSS Grid spec is given for [one item to ignore](https://github.com/w3c/csswg-drafts/issues/2117) `grid-gap`, we can utilize `grid-gap` by default instead of opting in to padding classes.
101 |
102 | ## FAQs
103 |
104 | ### Why does none of the CSS Grid code use `grid-gap` for gutters?
105 |
106 | A lot of times, you will want an item to break out of the gutters for background color, to extend media, or for another reason. Until the CSS Grid spec has a way to ignore that gutter, we use the padding classes (`.yourGrid-padding`) to opt-in to respecting the gutter. The padding classes are always half the size of a gutter for alignment.
107 |
108 | ### Why are columns using vw units and sometimes the calc function?
109 |
110 | Until Edge and Safari support
111 | [`display: subgrid`](https://developer.mozilla.org/en-US/docs/Web/CSS/display#Browser_compatibility),
112 | it will be difficult for you to write semantic HTML with CSS Grid Layout. We are
113 | able to take advantage of vw units and the calc function so you can embed your
114 | `.yourPrefix-grid` class inside of itself as much that is needed for you.
115 |
116 | ### Why are there no row classes for the legacy implementation?
117 |
118 | Thanks to flexbox’s wrapping functionality, nodes that specify rows are not necessary. Only create a node for a row if it has semantic or accessibility significance. You can keep embedding `.yourPrefix-grid` as necessary to accomplish this.
119 |
120 | ### What happens in the legacy implementation if I specify the column width for one breakpoint, but not the next larger breakpoint?
121 |
122 | To maintain a mobile-first opinion, column widths will scale to the next breakpoint if not specified. This means that a `.yourPrefix__col--sm--3` (with 6 total columns) would automatically grow into a `.yourPrefix__col--md--6` (with 12 total columns) if no `md` class was declared to maintain half of the screen size.
123 |
--------------------------------------------------------------------------------
/examples/bootstrap/README.md:
--------------------------------------------------------------------------------
1 | # Bootstrap Design Grid
2 |
3 | [View a random layout with this grid.](https://ibm.github.io/css-gridish/examples/bootstrap/index.html)
4 |
5 | An example of [CSS Gridish](../../README.md) generating CSS Grid code, fallback flexbox code, dev documentation, and Sketch files based on [Bootstrap’s grid.](https://getbootstrap.com/docs/4.0/layout/grid/)
6 |
7 | Check out everything CSS Gridish made based off of the [config file](./css-gridish.json) in the [css-gridish folder.](./css-gridish/)
8 |
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish.json:
--------------------------------------------------------------------------------
1 | {
2 | "prefix": "bootstrap",
3 | "breakpoints": {
4 | "sm": {
5 | "breakpoint": 36,
6 | "columns": 12,
7 | "gutter": "30px",
8 | "margin": 0
9 | },
10 | "xl": {
11 | "breakpoint": 100,
12 | "columns": 12,
13 | "gutter": "30px",
14 | "margin": 0
15 | }
16 | },
17 | "extraArtboards": {
18 | "md": 51,
19 | "lg": 66
20 | },
21 | "rem": 15,
22 | "rowHeight": 1,
23 | "rows": 30,
24 | "paths": {
25 | "intro": "intro.md"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/bootstrap-grid.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/examples/bootstrap/css-gridish/bootstrap-grid.sketch
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/css/bootstrap-grid-legacy.min.css:
--------------------------------------------------------------------------------
1 | html{font-size:15px}body{margin:0}.bootstrap-container{box-sizing:border-box;margin-left:auto;margin-right:auto;max-width:100rem;overflow-x:hidden;width:100vw}.bootstrap-container--left{margin-left:0}.bootstrap-container--right{margin-right:0}.bootstrap-grid{align-items:flex-start;box-sizing:border-box;display:flex;display:grid;flex-wrap:wrap;position:relative;grid-auto-rows:minmax(1rem,min-content);grid-template-columns:repeat(auto-fill,8.33vw)}.bootstrap-grid>*{box-sizing:border-box;width:100%;grid-column:span 12}.bootstrap-grid>* :last-child,.bootstrap-grid>* :last-child>:last-child,.bootstrap-grid>* :last-child>:last-child>:last-child{margin-bottom:0}[class*=bootstrap-padding]{box-sizing:border-box}@supports (display:grid){.bootstrap-grid{align-items:unset}.bootstrap-grid>*{width:initial;height:100%}:root{--bootstrap-height-1:1rem;--bootstrap-height-2:2rem;--bootstrap-height-3:3rem;--bootstrap-height-4:4rem;--bootstrap-height-5:5rem;--bootstrap-height-6:6rem;--bootstrap-height-7:7rem;--bootstrap-height-8:8rem;--bootstrap-height-9:9rem;--bootstrap-height-10:10rem;--bootstrap-height-11:11rem;--bootstrap-height-12:12rem;--bootstrap-height-13:13rem;--bootstrap-height-14:14rem;--bootstrap-height-15:15rem;--bootstrap-height-16:16rem;--bootstrap-height-17:17rem;--bootstrap-height-18:18rem;--bootstrap-height-19:19rem;--bootstrap-height-20:20rem;--bootstrap-height-21:21rem;--bootstrap-height-22:22rem;--bootstrap-height-23:23rem;--bootstrap-height-24:24rem;--bootstrap-height-25:25rem;--bootstrap-height-26:26rem;--bootstrap-height-27:27rem;--bootstrap-height-28:28rem;--bootstrap-height-29:29rem}}.bootstrap-grid__height--sm--0{height:0;min-height:0}.bootstrap-grid__height--sm--1{grid-row:span 1;height:1rem;min-height:1rem}.bootstrap-grid__height--sm--2{grid-row:span 2;height:2rem;min-height:2rem}.bootstrap-grid__height--sm--3{grid-row:span 3;height:3rem;min-height:3rem}.bootstrap-grid__height--sm--4{grid-row:span 4;height:4rem;min-height:4rem}.bootstrap-grid__height--sm--5{grid-row:span 5;height:5rem;min-height:5rem}.bootstrap-grid__height--sm--6{grid-row:span 6;height:6rem;min-height:6rem}.bootstrap-grid__height--sm--7{grid-row:span 7;height:7rem;min-height:7rem}.bootstrap-grid__height--sm--8{grid-row:span 8;height:8rem;min-height:8rem}.bootstrap-grid__height--sm--9{grid-row:span 9;height:9rem;min-height:9rem}.bootstrap-grid__height--sm--10{grid-row:span 10;height:10rem;min-height:10rem}.bootstrap-grid__height--sm--11{grid-row:span 11;height:11rem;min-height:11rem}.bootstrap-grid__height--sm--12{grid-row:span 12;height:12rem;min-height:12rem}.bootstrap-grid__height--sm--13{grid-row:span 13;height:13rem;min-height:13rem}.bootstrap-grid__height--sm--14{grid-row:span 14;height:14rem;min-height:14rem}.bootstrap-grid__height--sm--15{grid-row:span 15;height:15rem;min-height:15rem}.bootstrap-grid__height--sm--16{grid-row:span 16;height:16rem;min-height:16rem}.bootstrap-grid__height--sm--17{grid-row:span 17;height:17rem;min-height:17rem}.bootstrap-grid__height--sm--18{grid-row:span 18;height:18rem;min-height:18rem}.bootstrap-grid__height--sm--19{grid-row:span 19;height:19rem;min-height:19rem}.bootstrap-grid__height--sm--20{grid-row:span 20;height:20rem;min-height:20rem}.bootstrap-grid__height--sm--21{grid-row:span 21;height:21rem;min-height:21rem}.bootstrap-grid__height--sm--22{grid-row:span 22;height:22rem;min-height:22rem}.bootstrap-grid__height--sm--23{grid-row:span 23;height:23rem;min-height:23rem}.bootstrap-grid__height--sm--24{grid-row:span 24;height:24rem;min-height:24rem}.bootstrap-grid__height--sm--25{grid-row:span 25;height:25rem;min-height:25rem}.bootstrap-grid__height--sm--26{grid-row:span 26;height:26rem;min-height:26rem}.bootstrap-grid__height--sm--27{grid-row:span 27;height:27rem;min-height:27rem}.bootstrap-grid__height--sm--28{grid-row:span 28;height:28rem;min-height:28rem}.bootstrap-grid__height--sm--29{grid-row:span 29;height:29rem;min-height:29rem}[class*=bootstrap-grid__col--sm--]{display:block}.bootstrap-grid__col--sm--0,.bootstrap-grid__col--sm--0--only{display:none}.bootstrap-padding{padding:15px}.bootstrap-padding--bottom{padding-bottom:15px}.bootstrap-padding--left{padding-left:15px}.bootstrap-padding--right{padding-right:15px}.bootstrap-padding--top{padding-top:15px}.bootstrap-padding--horizontal{padding-left:15px;padding-right:15px}.bootstrap-padding--vertical{padding-bottom:15px;padding-top:15px}.bootstrap-grid.bootstrap-grid--fixed-columns{grid-template-columns:repeat(auto-fill,3rem)}.bootstrap-grid.bootstrap-grid--fluid-rows{grid-auto-rows:8.33vw}.bootstrap-grid__col--sm--1{max-width:8.33rem;width:8.33vw;grid-column:span 1}.bootstrap-grid__col--sm--1.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 1}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--1{grid-row:span 1;height:8.33vw;min-height:8.33vw;max-height:8.33rem}.bootstrap-grid__col--sm--2{max-width:16.66rem;width:16.66vw;grid-column:span 2}.bootstrap-grid__col--sm--2.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 2}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--2{grid-row:span 2;height:16.66vw;min-height:16.66vw;max-height:16.66rem}.bootstrap-grid__col--sm--3{max-width:25rem;width:25vw;grid-column:span 3}.bootstrap-grid__col--sm--3.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 3}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--3{grid-row:span 3;height:25vw;min-height:25vw;max-height:25rem}.bootstrap-grid__col--sm--4{max-width:33.33rem;width:33.33vw;grid-column:span 4}.bootstrap-grid__col--sm--4.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 4}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--4{grid-row:span 4;height:33.33vw;min-height:33.33vw;max-height:33.33rem}.bootstrap-grid__col--sm--5{max-width:41.66rem;width:41.66vw;grid-column:span 5}.bootstrap-grid__col--sm--5.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 5}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--5{grid-row:span 5;height:41.66vw;min-height:41.66vw;max-height:41.66rem}.bootstrap-grid__col--sm--6{max-width:50rem;width:50vw;grid-column:span 6}.bootstrap-grid__col--sm--6.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 6}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--6{grid-row:span 6;height:50vw;min-height:50vw;max-height:50rem}.bootstrap-grid__col--sm--7{max-width:58.33rem;width:58.33vw;grid-column:span 7}.bootstrap-grid__col--sm--7.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 7}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--7{grid-row:span 7;height:58.33vw;min-height:58.33vw;max-height:58.33rem}.bootstrap-grid__col--sm--8{max-width:66.66rem;width:66.66vw;grid-column:span 8}.bootstrap-grid__col--sm--8.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 8}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--8{grid-row:span 8;height:66.66vw;min-height:66.66vw;max-height:66.66rem}.bootstrap-grid__col--sm--9{max-width:75rem;width:75vw;grid-column:span 9}.bootstrap-grid__col--sm--9.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 9}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--9{grid-row:span 9;height:75vw;min-height:75vw;max-height:75rem}.bootstrap-grid__col--sm--10{max-width:83.33rem;width:83.33vw;grid-column:span 10}.bootstrap-grid__col--sm--10.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 10}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--10{grid-row:span 10;height:83.33vw;min-height:83.33vw;max-height:83.33rem}.bootstrap-grid__col--sm--11{max-width:91.66rem;width:91.66vw;grid-column:span 11}.bootstrap-grid__col--sm--11.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 11}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--11{grid-row:span 11;height:91.66vw;min-height:91.66vw;max-height:91.66rem}.bootstrap-grid__col--sm--12{max-width:100rem;width:100vw;grid-column:span 12}.bootstrap-grid__col--sm--12.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 12}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--12{grid-row:span 12;height:100vw;min-height:100vw;max-height:100rem}@media screen and (min-width:100rem){.bootstrap-grid__col--sm--0--only,[class*=bootstrap-grid__col--xl--]{display:block}.bootstrap-grid__col--xl--0,.bootstrap-grid__col--xl--0--only{display:none}.bootstrap-padding{padding:15px}.bootstrap-padding--bottom{padding-bottom:15px}.bootstrap-padding--left{padding-left:15px}.bootstrap-padding--right{padding-right:15px}.bootstrap-padding--top{padding-top:15px}.bootstrap-padding--horizontal{padding-left:15px;padding-right:15px}.bootstrap-padding--vertical{padding-bottom:15px;padding-top:15px}.bootstrap-grid{grid-template-columns:repeat(auto-fill,8.33rem)}.bootstrap-grid.bootstrap-grid--fixed-columns{grid-template-columns:repeat(auto-fill,8.33333rem)}.bootstrap-grid.bootstrap-grid--fluid-rows{grid-auto-rows:8.33rem}[class*=bootstrap-grid__col--]{min-width:0}}@supports (display:grid){.bootstrap-grid>*,.bootstrap-grid>[class*=bootstrap-grid__col--]{min-width:initial;max-width:initial;width:initial}.bootstrap-grid>.bootstrap-grid,.bootstrap-grid>[class*=bootstrap-grid__col--].bootstrap-grid{display:grid}.bootstrap-grid>[class*=bootstrap-grid__height--]{height:unset;max-height:unset;min-height:initial}}.bootstrap-grid>script{display:none}
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/css/bootstrap-grid.css:
--------------------------------------------------------------------------------
1 | html {
2 | font-size: 15px; }
3 |
4 | body {
5 | margin: 0; }
6 |
7 | .bootstrap-container {
8 | box-sizing: border-box;
9 | margin-left: auto;
10 | margin-right: auto;
11 | max-width: 100rem;
12 | overflow-x: hidden;
13 | width: 100vw; }
14 |
15 | .bootstrap-container--left {
16 | margin-left: 0; }
17 |
18 | .bootstrap-container--right {
19 | margin-right: 0; }
20 |
21 | .bootstrap-grid {
22 | align-items: flex-start;
23 | box-sizing: border-box;
24 | display: grid;
25 | flex-wrap: wrap;
26 | position: relative; }
27 | .bootstrap-grid > * {
28 | box-sizing: border-box; }
29 | .bootstrap-grid > * :last-child,
30 | .bootstrap-grid > * :last-child > :last-child,
31 | .bootstrap-grid > * :last-child > :last-child > :last-child {
32 | margin-bottom: 0; }
33 |
34 | [class*="bootstrap-padding"] {
35 | box-sizing: border-box; }
36 |
37 | @supports (display: grid) {
38 | .bootstrap-grid > * {
39 | height: 100%; } }
40 |
41 | :root {
42 | --bootstrap-height-1: 1rem;
43 | --bootstrap-height-2: 2rem;
44 | --bootstrap-height-3: 3rem;
45 | --bootstrap-height-4: 4rem;
46 | --bootstrap-height-5: 5rem;
47 | --bootstrap-height-6: 6rem;
48 | --bootstrap-height-7: 7rem;
49 | --bootstrap-height-8: 8rem;
50 | --bootstrap-height-9: 9rem;
51 | --bootstrap-height-10: 10rem;
52 | --bootstrap-height-11: 11rem;
53 | --bootstrap-height-12: 12rem;
54 | --bootstrap-height-13: 13rem;
55 | --bootstrap-height-14: 14rem;
56 | --bootstrap-height-15: 15rem;
57 | --bootstrap-height-16: 16rem;
58 | --bootstrap-height-17: 17rem;
59 | --bootstrap-height-18: 18rem;
60 | --bootstrap-height-19: 19rem;
61 | --bootstrap-height-20: 20rem;
62 | --bootstrap-height-21: 21rem;
63 | --bootstrap-height-22: 22rem;
64 | --bootstrap-height-23: 23rem;
65 | --bootstrap-height-24: 24rem;
66 | --bootstrap-height-25: 25rem;
67 | --bootstrap-height-26: 26rem;
68 | --bootstrap-height-27: 27rem;
69 | --bootstrap-height-28: 28rem;
70 | --bootstrap-height-29: 29rem; }
71 |
72 | .bootstrap-grid__height--sm--0 {
73 | height: 0;
74 | min-height: 0; }
75 |
76 | .bootstrap-grid__height--sm--1 {
77 | grid-row: span 1; }
78 |
79 | .bootstrap-grid__height--sm--2 {
80 | grid-row: span 2; }
81 |
82 | .bootstrap-grid__height--sm--3 {
83 | grid-row: span 3; }
84 |
85 | .bootstrap-grid__height--sm--4 {
86 | grid-row: span 4; }
87 |
88 | .bootstrap-grid__height--sm--5 {
89 | grid-row: span 5; }
90 |
91 | .bootstrap-grid__height--sm--6 {
92 | grid-row: span 6; }
93 |
94 | .bootstrap-grid__height--sm--7 {
95 | grid-row: span 7; }
96 |
97 | .bootstrap-grid__height--sm--8 {
98 | grid-row: span 8; }
99 |
100 | .bootstrap-grid__height--sm--9 {
101 | grid-row: span 9; }
102 |
103 | .bootstrap-grid__height--sm--10 {
104 | grid-row: span 10; }
105 |
106 | .bootstrap-grid__height--sm--11 {
107 | grid-row: span 11; }
108 |
109 | .bootstrap-grid__height--sm--12 {
110 | grid-row: span 12; }
111 |
112 | .bootstrap-grid__height--sm--13 {
113 | grid-row: span 13; }
114 |
115 | .bootstrap-grid__height--sm--14 {
116 | grid-row: span 14; }
117 |
118 | .bootstrap-grid__height--sm--15 {
119 | grid-row: span 15; }
120 |
121 | .bootstrap-grid__height--sm--16 {
122 | grid-row: span 16; }
123 |
124 | .bootstrap-grid__height--sm--17 {
125 | grid-row: span 17; }
126 |
127 | .bootstrap-grid__height--sm--18 {
128 | grid-row: span 18; }
129 |
130 | .bootstrap-grid__height--sm--19 {
131 | grid-row: span 19; }
132 |
133 | .bootstrap-grid__height--sm--20 {
134 | grid-row: span 20; }
135 |
136 | .bootstrap-grid__height--sm--21 {
137 | grid-row: span 21; }
138 |
139 | .bootstrap-grid__height--sm--22 {
140 | grid-row: span 22; }
141 |
142 | .bootstrap-grid__height--sm--23 {
143 | grid-row: span 23; }
144 |
145 | .bootstrap-grid__height--sm--24 {
146 | grid-row: span 24; }
147 |
148 | .bootstrap-grid__height--sm--25 {
149 | grid-row: span 25; }
150 |
151 | .bootstrap-grid__height--sm--26 {
152 | grid-row: span 26; }
153 |
154 | .bootstrap-grid__height--sm--27 {
155 | grid-row: span 27; }
156 |
157 | .bootstrap-grid__height--sm--28 {
158 | grid-row: span 28; }
159 |
160 | .bootstrap-grid__height--sm--29 {
161 | grid-row: span 29; }
162 |
163 | [class*="bootstrap-grid__col--sm--"] {
164 | display: block; }
165 |
166 | .bootstrap-grid__col--sm--0,
167 | .bootstrap-grid__col--sm--0--only {
168 | display: none; }
169 |
170 | .bootstrap-padding {
171 | padding: 15px; }
172 |
173 | .bootstrap-padding--bottom {
174 | padding-bottom: 15px; }
175 |
176 | .bootstrap-padding--left {
177 | padding-left: 15px; }
178 |
179 | .bootstrap-padding--right {
180 | padding-right: 15px; }
181 |
182 | .bootstrap-padding--top {
183 | padding-top: 15px; }
184 |
185 | .bootstrap-padding--horizontal {
186 | padding-left: 15px;
187 | padding-right: 15px; }
188 |
189 | .bootstrap-padding--vertical {
190 | padding-bottom: 15px;
191 | padding-top: 15px; }
192 |
193 | .bootstrap-grid {
194 | grid-auto-rows: minmax(1rem, min-content);
195 | grid-template-columns: repeat(auto-fill, 8.33vw); }
196 | .bootstrap-grid.bootstrap-grid--fixed-columns {
197 | grid-template-columns: repeat(auto-fill, 3rem); }
198 | .bootstrap-grid.bootstrap-grid--fluid-rows {
199 | grid-auto-rows: 8.33vw; }
200 | .bootstrap-grid > * {
201 | grid-column: span 12; }
202 |
203 | .bootstrap-grid__col--sm--1 {
204 | grid-column: span 1; }
205 | .bootstrap-grid__col--sm--1.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
206 | grid-column: span 1; }
207 |
208 | .bootstrap-grid--fluid-rows
209 | > .bootstrap-grid__height--sm--1 {
210 | grid-row: span 1; }
211 |
212 | .bootstrap-grid__col--sm--2 {
213 | grid-column: span 2; }
214 | .bootstrap-grid__col--sm--2.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
215 | grid-column: span 2; }
216 |
217 | .bootstrap-grid--fluid-rows
218 | > .bootstrap-grid__height--sm--2 {
219 | grid-row: span 2; }
220 |
221 | .bootstrap-grid__col--sm--3 {
222 | grid-column: span 3; }
223 | .bootstrap-grid__col--sm--3.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
224 | grid-column: span 3; }
225 |
226 | .bootstrap-grid--fluid-rows
227 | > .bootstrap-grid__height--sm--3 {
228 | grid-row: span 3; }
229 |
230 | .bootstrap-grid__col--sm--4 {
231 | grid-column: span 4; }
232 | .bootstrap-grid__col--sm--4.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
233 | grid-column: span 4; }
234 |
235 | .bootstrap-grid--fluid-rows
236 | > .bootstrap-grid__height--sm--4 {
237 | grid-row: span 4; }
238 |
239 | .bootstrap-grid__col--sm--5 {
240 | grid-column: span 5; }
241 | .bootstrap-grid__col--sm--5.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
242 | grid-column: span 5; }
243 |
244 | .bootstrap-grid--fluid-rows
245 | > .bootstrap-grid__height--sm--5 {
246 | grid-row: span 5; }
247 |
248 | .bootstrap-grid__col--sm--6 {
249 | grid-column: span 6; }
250 | .bootstrap-grid__col--sm--6.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
251 | grid-column: span 6; }
252 |
253 | .bootstrap-grid--fluid-rows
254 | > .bootstrap-grid__height--sm--6 {
255 | grid-row: span 6; }
256 |
257 | .bootstrap-grid__col--sm--7 {
258 | grid-column: span 7; }
259 | .bootstrap-grid__col--sm--7.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
260 | grid-column: span 7; }
261 |
262 | .bootstrap-grid--fluid-rows
263 | > .bootstrap-grid__height--sm--7 {
264 | grid-row: span 7; }
265 |
266 | .bootstrap-grid__col--sm--8 {
267 | grid-column: span 8; }
268 | .bootstrap-grid__col--sm--8.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
269 | grid-column: span 8; }
270 |
271 | .bootstrap-grid--fluid-rows
272 | > .bootstrap-grid__height--sm--8 {
273 | grid-row: span 8; }
274 |
275 | .bootstrap-grid__col--sm--9 {
276 | grid-column: span 9; }
277 | .bootstrap-grid__col--sm--9.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
278 | grid-column: span 9; }
279 |
280 | .bootstrap-grid--fluid-rows
281 | > .bootstrap-grid__height--sm--9 {
282 | grid-row: span 9; }
283 |
284 | .bootstrap-grid__col--sm--10 {
285 | grid-column: span 10; }
286 | .bootstrap-grid__col--sm--10.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
287 | grid-column: span 10; }
288 |
289 | .bootstrap-grid--fluid-rows
290 | > .bootstrap-grid__height--sm--10 {
291 | grid-row: span 10; }
292 |
293 | .bootstrap-grid__col--sm--11 {
294 | grid-column: span 11; }
295 | .bootstrap-grid__col--sm--11.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
296 | grid-column: span 11; }
297 |
298 | .bootstrap-grid--fluid-rows
299 | > .bootstrap-grid__height--sm--11 {
300 | grid-row: span 11; }
301 |
302 | .bootstrap-grid__col--sm--12 {
303 | grid-column: span 12; }
304 | .bootstrap-grid__col--sm--12.bootstrap-grid > *:not([class*="bootstrap-grid__col"]) {
305 | grid-column: span 12; }
306 |
307 | .bootstrap-grid--fluid-rows
308 | > .bootstrap-grid__height--sm--12 {
309 | grid-row: span 12; }
310 |
311 | @media screen and (min-width: 100rem) {
312 | .bootstrap-grid__col--sm--0--only {
313 | display: block; }
314 | [class*="bootstrap-grid__col--xl--"] {
315 | display: block; }
316 | .bootstrap-grid__col--xl--0,
317 | .bootstrap-grid__col--xl--0--only {
318 | display: none; }
319 | .bootstrap-padding {
320 | padding: 15px; }
321 | .bootstrap-padding--bottom {
322 | padding-bottom: 15px; }
323 | .bootstrap-padding--left {
324 | padding-left: 15px; }
325 | .bootstrap-padding--right {
326 | padding-right: 15px; }
327 | .bootstrap-padding--top {
328 | padding-top: 15px; }
329 | .bootstrap-padding--horizontal {
330 | padding-left: 15px;
331 | padding-right: 15px; }
332 | .bootstrap-padding--vertical {
333 | padding-bottom: 15px;
334 | padding-top: 15px; }
335 | .bootstrap-grid {
336 | grid-template-columns: repeat(auto-fill, 8.33rem); }
337 | .bootstrap-grid.bootstrap-grid--fixed-columns {
338 | grid-template-columns: repeat(auto-fill, 8.33333rem); }
339 | .bootstrap-grid.bootstrap-grid--fluid-rows {
340 | grid-auto-rows: 8.33rem; } }
341 |
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/css/bootstrap-grid.min.css:
--------------------------------------------------------------------------------
1 | html{font-size:15px}body{margin:0}.bootstrap-container{box-sizing:border-box;margin-left:auto;margin-right:auto;max-width:100rem;overflow-x:hidden;width:100vw}.bootstrap-container--left{margin-left:0}.bootstrap-container--right{margin-right:0}.bootstrap-grid{align-items:flex-start;box-sizing:border-box;display:grid;flex-wrap:wrap;position:relative;grid-auto-rows:minmax(1rem,min-content);grid-template-columns:repeat(auto-fill,8.33vw)}.bootstrap-grid>*{box-sizing:border-box;grid-column:span 12}.bootstrap-grid>* :last-child,.bootstrap-grid>* :last-child>:last-child,.bootstrap-grid>* :last-child>:last-child>:last-child{margin-bottom:0}[class*=bootstrap-padding]{box-sizing:border-box}@supports (display:grid){.bootstrap-grid>*{height:100%}}:root{--bootstrap-height-1:1rem;--bootstrap-height-2:2rem;--bootstrap-height-3:3rem;--bootstrap-height-4:4rem;--bootstrap-height-5:5rem;--bootstrap-height-6:6rem;--bootstrap-height-7:7rem;--bootstrap-height-8:8rem;--bootstrap-height-9:9rem;--bootstrap-height-10:10rem;--bootstrap-height-11:11rem;--bootstrap-height-12:12rem;--bootstrap-height-13:13rem;--bootstrap-height-14:14rem;--bootstrap-height-15:15rem;--bootstrap-height-16:16rem;--bootstrap-height-17:17rem;--bootstrap-height-18:18rem;--bootstrap-height-19:19rem;--bootstrap-height-20:20rem;--bootstrap-height-21:21rem;--bootstrap-height-22:22rem;--bootstrap-height-23:23rem;--bootstrap-height-24:24rem;--bootstrap-height-25:25rem;--bootstrap-height-26:26rem;--bootstrap-height-27:27rem;--bootstrap-height-28:28rem;--bootstrap-height-29:29rem}.bootstrap-grid__height--sm--0{height:0;min-height:0}.bootstrap-grid__height--sm--1{grid-row:span 1}.bootstrap-grid__height--sm--2{grid-row:span 2}.bootstrap-grid__height--sm--3{grid-row:span 3}.bootstrap-grid__height--sm--4{grid-row:span 4}.bootstrap-grid__height--sm--5{grid-row:span 5}.bootstrap-grid__height--sm--6{grid-row:span 6}.bootstrap-grid__height--sm--7{grid-row:span 7}.bootstrap-grid__height--sm--8{grid-row:span 8}.bootstrap-grid__height--sm--9{grid-row:span 9}.bootstrap-grid__height--sm--10{grid-row:span 10}.bootstrap-grid__height--sm--11{grid-row:span 11}.bootstrap-grid__height--sm--12{grid-row:span 12}.bootstrap-grid__height--sm--13{grid-row:span 13}.bootstrap-grid__height--sm--14{grid-row:span 14}.bootstrap-grid__height--sm--15{grid-row:span 15}.bootstrap-grid__height--sm--16{grid-row:span 16}.bootstrap-grid__height--sm--17{grid-row:span 17}.bootstrap-grid__height--sm--18{grid-row:span 18}.bootstrap-grid__height--sm--19{grid-row:span 19}.bootstrap-grid__height--sm--20{grid-row:span 20}.bootstrap-grid__height--sm--21{grid-row:span 21}.bootstrap-grid__height--sm--22{grid-row:span 22}.bootstrap-grid__height--sm--23{grid-row:span 23}.bootstrap-grid__height--sm--24{grid-row:span 24}.bootstrap-grid__height--sm--25{grid-row:span 25}.bootstrap-grid__height--sm--26{grid-row:span 26}.bootstrap-grid__height--sm--27{grid-row:span 27}.bootstrap-grid__height--sm--28{grid-row:span 28}.bootstrap-grid__height--sm--29{grid-row:span 29}[class*=bootstrap-grid__col--sm--]{display:block}.bootstrap-grid__col--sm--0,.bootstrap-grid__col--sm--0--only{display:none}.bootstrap-padding{padding:15px}.bootstrap-padding--bottom{padding-bottom:15px}.bootstrap-padding--left{padding-left:15px}.bootstrap-padding--right{padding-right:15px}.bootstrap-padding--top{padding-top:15px}.bootstrap-padding--horizontal{padding-left:15px;padding-right:15px}.bootstrap-padding--vertical{padding-bottom:15px;padding-top:15px}.bootstrap-grid.bootstrap-grid--fixed-columns{grid-template-columns:repeat(auto-fill,3rem)}.bootstrap-grid.bootstrap-grid--fluid-rows{grid-auto-rows:8.33vw}.bootstrap-grid__col--sm--1,.bootstrap-grid__col--sm--1.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 1}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--1{grid-row:span 1}.bootstrap-grid__col--sm--2,.bootstrap-grid__col--sm--2.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 2}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--2{grid-row:span 2}.bootstrap-grid__col--sm--3,.bootstrap-grid__col--sm--3.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 3}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--3{grid-row:span 3}.bootstrap-grid__col--sm--4,.bootstrap-grid__col--sm--4.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 4}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--4{grid-row:span 4}.bootstrap-grid__col--sm--5,.bootstrap-grid__col--sm--5.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 5}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--5{grid-row:span 5}.bootstrap-grid__col--sm--6,.bootstrap-grid__col--sm--6.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 6}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--6{grid-row:span 6}.bootstrap-grid__col--sm--7,.bootstrap-grid__col--sm--7.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 7}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--7{grid-row:span 7}.bootstrap-grid__col--sm--8,.bootstrap-grid__col--sm--8.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 8}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--8{grid-row:span 8}.bootstrap-grid__col--sm--9,.bootstrap-grid__col--sm--9.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 9}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--9{grid-row:span 9}.bootstrap-grid__col--sm--10,.bootstrap-grid__col--sm--10.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 10}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--10{grid-row:span 10}.bootstrap-grid__col--sm--11,.bootstrap-grid__col--sm--11.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 11}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--11{grid-row:span 11}.bootstrap-grid__col--sm--12,.bootstrap-grid__col--sm--12.bootstrap-grid>:not([class*=bootstrap-grid__col]){grid-column:span 12}.bootstrap-grid--fluid-rows>.bootstrap-grid__height--sm--12{grid-row:span 12}@media screen and (min-width:100rem){.bootstrap-grid__col--sm--0--only,[class*=bootstrap-grid__col--xl--]{display:block}.bootstrap-grid__col--xl--0,.bootstrap-grid__col--xl--0--only{display:none}.bootstrap-padding{padding:15px}.bootstrap-padding--bottom{padding-bottom:15px}.bootstrap-padding--left{padding-left:15px}.bootstrap-padding--right{padding-right:15px}.bootstrap-padding--top{padding-top:15px}.bootstrap-padding--horizontal{padding-left:15px;padding-right:15px}.bootstrap-padding--vertical{padding-bottom:15px;padding-top:15px}.bootstrap-grid{grid-template-columns:repeat(auto-fill,8.33rem)}.bootstrap-grid.bootstrap-grid--fixed-columns{grid-template-columns:repeat(auto-fill,8.33333rem)}.bootstrap-grid.bootstrap-grid--fluid-rows{grid-auto-rows:8.33rem}}
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/scss/_core.scss:
--------------------------------------------------------------------------------
1 | @import "functions.scss";
2 | @import "mixins.scss";
3 | @import "variables.scss";
4 | @import "utilities.scss";
5 |
6 | html {
7 | font-size: map-get($grid-values, "rem") * 1px;
8 | }
9 |
10 | body {
11 | margin: 0;
12 | }
13 |
14 | .#{$prefix}-container {
15 | box-sizing: border-box;
16 | margin-left: auto;
17 | margin-right: auto;
18 | max-width: #{map-get($last, breakpoint)}rem;
19 | overflow-x: hidden;
20 | width: 100vw;
21 | }
22 |
23 | .#{$prefix}-container--left {
24 | margin-left: 0;
25 | }
26 |
27 | .#{$prefix}-container--right {
28 | margin-right: 0;
29 | }
30 |
31 | .#{$prefix}-grid {
32 | align-items: flex-start;
33 | box-sizing: border-box;
34 | @if $includeFlexFallback {
35 | display: flex;
36 | }
37 | display: grid;
38 | flex-wrap: wrap;
39 | position: relative;
40 |
41 | > * {
42 | box-sizing: border-box;
43 |
44 | :last-child,
45 | :last-child > :last-child,
46 | :last-child > :last-child > :last-child {
47 | margin-bottom: 0;
48 | }
49 | }
50 | }
51 |
52 | [class*="#{$prefix}-padding"] {
53 | box-sizing: border-box;
54 | }
55 |
56 | // Rules needed in legacy, but needed to change in CSS Grid
57 | @if $includeFlexFallback {
58 | .#{$prefix}-grid > * {
59 | width: 100%;
60 | }
61 |
62 | @supports (display: grid) {
63 | .#{$prefix}-grid {
64 | align-items: unset;
65 | }
66 |
67 | .#{$prefix}-grid > * {
68 | width: initial;
69 | }
70 | }
71 | }
72 |
73 | // Rules not needed in legacy, but needed in CSS Grid
74 | @supports (display: grid) {
75 | .#{$prefix}-grid > * {
76 | height: 100%;
77 | }
78 | }
79 |
80 | @include grid-legacy-wrapper($includeFlexFallback) {
81 | :root {
82 | @include grid-heights-fixed($rows);
83 | }
84 | }
85 |
86 | @each $name, $breakpoint in $allBreakpoints {
87 | @include media-query($name) {
88 | @if is-same-breakpoint($breakpoint, $last) == false {
89 | @include grid-legacy-heights($name);
90 | }
91 | @include grid-legacy-zeros($breakpoint, $name);
92 | @include grid-padding($breakpoint);
93 | @include grid($breakpoint, $name);
94 | @include grid-legacy-columns($breakpoint, $name);
95 |
96 | // Wrap all bleed/break classes and css variables in a CSS Grid support query
97 | @include grid-legacy-wrapper($includeFlexFallback) {
98 | @include grid-margin($breakpoint, $name);
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/scss/_functions.scss:
--------------------------------------------------------------------------------
1 | @import "sass-list-maps";
2 |
3 | // Transform the gutter property into a padding property for web
4 | @function add-padding($breakpoints) {
5 | $cleanBreakpoints: ();
6 | @each $name, $breakpoint in $breakpoints {
7 | $cleanBreakpoints: map-merge(
8 | $cleanBreakpoints,
9 | (
10 | $name:
11 | map-merge($breakpoint, (padding: map-get($breakpoint, gutter) / 2))
12 | )
13 | );
14 | }
15 |
16 | @return $cleanBreakpoints;
17 | }
18 |
19 | // Merge standard and custom breakpoints into list
20 | @function all-breakpoints($breakpoints, $extraBreakpoints, $first, $last) {
21 | $allBreakpoints: $breakpoints;
22 | @each $currentBreakpoint in $extraBreakpoints {
23 | $extraBreakpointName: nth($currentBreakpoint, 1);
24 | $extraBreakpointWidth: nth($currentBreakpoint, 2);
25 | $found: false;
26 | $match: null;
27 | @each $majorBreakpoint in $breakpoints {
28 | @if $found == false {
29 | @if map-get(nth($majorBreakpoint, 2), breakpoint) >
30 | $extraBreakpointWidth
31 | {
32 | $found: true;
33 | } @else {
34 | $match: $majorBreakpoint;
35 | }
36 | }
37 | }
38 | @if $extraBreakpointWidth > map-get($last, breakpoint) {
39 | $match: (
40 | last,
41 | $last
42 | );
43 | }
44 | @if $extraBreakpointWidth < map-get($first, breakpoint) {
45 | $match: (
46 | first,
47 | $first
48 | );
49 | }
50 |
51 | $newBreakpoint: map-merge(
52 | nth($match, 2),
53 | (breakpoint: $extraBreakpointWidth)
54 | );
55 | $currentBreakpoint: (
56 | $extraBreakpointName:
57 | map-merge(nth($match, 2), (breakpoint: $extraBreakpointWidth))
58 | );
59 | $allBreakpoints: map-merge($allBreakpoints, $currentBreakpoint);
60 | }
61 |
62 | @return maps-sort($allBreakpoints, breakpoint);
63 | }
64 |
65 | @function is-same-breakpoint($a, $b) {
66 | @return map-get($a, breakpoint) == map-get($b, breakpoint);
67 | }
68 |
69 | /// Traverse maps and retrieve deeply nested values: https://css-tricks.com/snippets/sass/deep-getset-maps/
70 | /// @author Hugo Giraudel
71 | /// @param {Map} $map A sass map and any number of keys.
72 | /// @param {*} $keys Nested values.
73 | /// @return Nested values or nested map.
74 | @function map-deep-get($map, $keys...) {
75 | @each $key in $keys {
76 | $map: map-get($map, $key);
77 | }
78 | @return $map;
79 | }
80 |
81 | // _decimal.scss | MIT License | gist.github.com/terkel/4373420
82 | @function round-decimal($number, $digits: 0, $mode: round) {
83 | $n: 1;
84 | // $number must be a number
85 | @if type-of($number) != number {
86 | @warn "#{ $number } is not a number.";
87 | @return $number;
88 | }
89 | // $digits must be a unitless number
90 | @if type-of($digits) != number {
91 | @warn "#{ $digits } is not a number.";
92 | @return $number;
93 | } @else if not unitless($digits) {
94 | @warn "#{ $digits } has a unit.";
95 | @return $number;
96 | }
97 | @for $i from 1 through $digits {
98 | $n: $n * 10;
99 | }
100 | @if $mode == round {
101 | @return round($number * $n) / $n;
102 | } @else if $mode == ceil {
103 | @return ceil($number * $n) / $n;
104 | } @else if $mode == floor {
105 | @return floor($number * $n) / $n;
106 | } @else {
107 | @warn "#{ $mode } is undefined keyword.";
108 | @return $number;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Set the width of a grid’s column
2 | @mixin grid($breakpoint, $breakpointName) {
3 | @if (map-get($breakpoint, columns) != null) {
4 | $columnSize: get-fluid-size($breakpointName, 1);
5 |
6 | .#{$prefix}-grid {
7 | @if is-same-breakpoint($breakpoint, $first) {
8 | grid-auto-rows: minmax($rowHeight * 1rem, min-content);
9 | }
10 | grid-template-columns: repeat(auto-fill, $columnSize);
11 |
12 | &.#{$prefix}-grid--fixed-columns {
13 | grid-template-columns: repeat(
14 | auto-fill,
15 | map-get($breakpoint, breakpoint) *
16 | 1rem /
17 | map-get($breakpoint, columns)
18 | );
19 | }
20 |
21 | &.#{$prefix}-grid--fluid-rows {
22 | grid-auto-rows: $columnSize;
23 | }
24 |
25 | @if is-same-breakpoint($breakpoint, $last) == false {
26 | > * {
27 | grid-column: span #{map-get($breakpoint, columns)};
28 | }
29 | }
30 | }
31 | }
32 | }
33 |
34 | // Generate variables for commonly used rows
35 | @mixin grid-heights-fixed($rows) {
36 | @for $i from 1 to $rows {
37 | --#{$prefix}-height-#{$i}: get-fixed-size($i);
38 | }
39 | }
40 |
41 | // Set the width of a grid’s column for legacy grid
42 | @mixin grid-legacy-columns($breakpoint, $name) {
43 | // Do not make class if last media query
44 | @if is-same-breakpoint($breakpoint, $last) == false {
45 | // Loop each breakpoint to insert previous breakpoint classes inside this breakpoint’s media query
46 | // Ex: Make sure .yourPrefix-grid__col--sm--2 has correct sizes in the lg media query
47 | @each $currentName, $currentBreakpoint in $allBreakpoints {
48 | // Check if current breakpoint is not bigger than current media query
49 | @if map-get($breakpoint, breakpoint) >=
50 | map-get($currentBreakpoint, breakpoint)
51 | {
52 | // Loop each column in current breakpoint for new class
53 | // Ex: .yourPrefix-grid__col--sm--1, .yourPrefix-grid__col--sm--2, etc.
54 | @for $i from 1 through map-get($currentBreakpoint, columns) {
55 | $columnMultiplier: $i *
56 | map-get($breakpoint, columns) /
57 | map-get($currentBreakpoint, columns);
58 | $columnSize: get-fluid-size($name, $columnMultiplier);
59 |
60 | $isSecondToLast: is-same-breakpoint(
61 | $breakpoint,
62 | nth(nth($allBreakpoints, length($allBreakpoints) - 1), 2)
63 | );
64 |
65 | $maxColumnSize: get-fluid-size(
66 | nth(nth($allBreakpoints, length($allBreakpoints)), 1),
67 | $columnMultiplier
68 | );
69 |
70 | .#{$prefix}-grid__col--#{$currentName}--#{$i} {
71 | @if $includeFlexFallback {
72 | // If second-to-last media query, apply max-width instead of remaking classes in last media query
73 | @if $isSecondToLast {
74 | max-width: $maxColumnSize;
75 | }
76 | width: $columnSize;
77 | }
78 | grid-column: span #{$columnMultiplier};
79 |
80 | @if is-same-breakpoint($breakpoint, $last) == false {
81 | &.#{$prefix}-grid > *:not([class*="#{$prefix}-grid__col"]) {
82 | grid-column: span #{$i};
83 | }
84 | }
85 | }
86 |
87 | .#{$prefix}-grid--fluid-rows
88 | > .#{$prefix}-grid__height--#{$currentName}--#{$i} {
89 | grid-row: span $i;
90 | @if $includeFlexFallback {
91 | height: $columnSize;
92 | min-height: $columnSize;
93 | // If second-to-last media query, apply max-height instead of remaking classes in last media query
94 | @if $isSecondToLast {
95 | max-height: $maxColumnSize;
96 | }
97 | }
98 | }
99 | }
100 | }
101 | }
102 | }
103 |
104 | @if $includeFlexFallback {
105 | @if is-same-breakpoint($breakpoint, $last) {
106 | [class*="#{$prefix}-grid__col--"] {
107 | min-width: 0;
108 | }
109 | }
110 | }
111 | }
112 |
113 | // Set the height of an item for legacy grid
114 | @mixin grid-legacy-heights($name) {
115 | .#{$prefix}-grid__height--#{$name}--0 {
116 | height: 0;
117 | min-height: 0;
118 | }
119 | @for $i from 1 to $rows {
120 | .#{$prefix}-grid__height--#{$name}--#{$i} {
121 | grid-row: span $i;
122 | @if $includeFlexFallback {
123 | height: get-fixed-size($i);
124 | min-height: get-fixed-size($i);
125 | }
126 | }
127 | }
128 | }
129 |
130 | // If we need legacy grid, wrap this content in support tag
131 | @mixin grid-legacy-wrapper($includeFlexFallback) {
132 | @if $includeFlexFallback {
133 | @supports (display: grid) {
134 | @content;
135 | }
136 | } @else {
137 | @content;
138 | }
139 | }
140 |
141 | // Generate all classes for 0 and 0-only displaying, including custom breakpoints if they exist
142 | @mixin grid-legacy-zeros($breakpoint, $name) {
143 | // Undo previous breakpoint’s 0--only class
144 | @for $i from length($allBreakpoints) * -1 through -1 {
145 | $currentBreakpoint: nth($allBreakpoints, $i);
146 | @if map-get(nth($currentBreakpoint, 2), breakpoint) <
147 | map-get($breakpoint, breakpoint)
148 | {
149 | .#{$prefix}-grid__col--#{nth($currentBreakpoint, 1)}--0--only {
150 | display: block;
151 | }
152 | }
153 | }
154 |
155 | [class*="#{$prefix}-grid__col--#{$name}--"] {
156 | display: block;
157 | }
158 |
159 | .#{$prefix}-grid__col--#{$name}--0,
160 | .#{$prefix}-grid__col--#{$name}--0--only {
161 | display: none;
162 | }
163 | }
164 |
165 | // Set the width of a grid’s margin
166 | // and allow for a child to break out of the grid’s margin
167 | @mixin grid-margin($breakpoint, $name) {
168 | $nameToUse: $name;
169 | $margin: #{map-get($breakpoint, margin)};
170 | $padding: #{map-get($breakpoint, padding)};
171 |
172 | // If last breakpoint, we use the previous breakpoint name
173 | // to treat the last breakpoint as the max-width of the previous breakpoint
174 | @if is-same-breakpoint($breakpoint, $last) == true {
175 | $previousBreakpoint: nth(
176 | $allBreakpoints,
177 | index(map-keys($allBreakpoints), $name) - 1
178 | );
179 | $nameToUse: nth($previousBreakpoint, 1);
180 | }
181 |
182 | // Undo previous breakpoint’s bleeds and breaks
183 | @if is-same-breakpoint($breakpoint, $first) ==
184 | false and
185 | is-same-breakpoint($breakpoint, $last) ==
186 | false
187 | {
188 | $previousBreakpoint: nth(
189 | $allBreakpoints,
190 | index(map-keys($allBreakpoints), $name) - 1
191 | );
192 | $previousName: nth($previousBreakpoint, 1);
193 | $previousMargin: map-get(nth($previousBreakpoint, 2), margin);
194 |
195 | @if $previousMargin !=
196 | null and
197 | $previousMargin !=
198 | 0 and
199 | $previousMargin !=
200 | "0"
201 | {
202 | [class^="#{$prefix}-container__bleed--#{$previousName}"],
203 | [class^="#{$prefix}-container__break--#{$previousName}"] {
204 | margin-left: 0;
205 | margin-right: 0;
206 | padding-left: 0;
207 | padding-right: 0;
208 |
209 | &[class^="#{$prefix}-padding"] {
210 | padding-left: $padding;
211 | padding-right: $padding;
212 | }
213 | }
214 | }
215 | }
216 |
217 | @if $margin != null and $margin != 0 and $margin != "0" {
218 | $marginPlusPadding: calc(#{$margin} + #{$padding});
219 | @if $margin == "0" and $padding == "0" {
220 | $marginPlusPadding: 0;
221 | } @else if $margin == "0" {
222 | $marginPlusPadding: $padding;
223 | } @else if $padding == "0" {
224 | $marginPlusPadding: $margin;
225 | }
226 |
227 | .#{$prefix}-container {
228 | margin-left: auto;
229 | margin-right: auto;
230 | padding-left: $margin;
231 | padding-right: $margin;
232 | }
233 |
234 | .#{$prefix}-container--left {
235 | margin-left: 0;
236 | }
237 |
238 | .#{$prefix}-container--right {
239 | margin-right: 0;
240 | }
241 |
242 | .#{$prefix}-container__bleed--#{$nameToUse},
243 | .#{$prefix}-container__bleed--#{$nameToUse}--left,
244 | .#{$prefix}-container__break--#{$nameToUse},
245 | .#{$prefix}-container__break--#{$nameToUse}--left {
246 | margin-left: -#{$margin};
247 | }
248 |
249 | .#{$prefix}-container__bleed--#{$nameToUse},
250 | .#{$prefix}-container__bleed--#{$nameToUse}--right,
251 | .#{$prefix}-container__break--#{$nameToUse},
252 | .#{$prefix}-container__break--#{$nameToUse}--right {
253 | margin-right: -#{$margin};
254 | }
255 |
256 | .#{$prefix}-container__bleed--#{$nameToUse},
257 | .#{$prefix}-container__bleed--#{$nameToUse}--left {
258 | padding-left: $margin;
259 |
260 | &.#{$prefix}-padding,
261 | &.#{$prefix}-padding--horizontal,
262 | &.#{$prefix}-padding--left {
263 | padding-left: $marginPlusPadding;
264 | }
265 | }
266 |
267 | .#{$prefix}-container__bleed--#{$nameToUse},
268 | .#{$prefix}-container__bleed--#{$nameToUse}--right {
269 | padding-right: $margin;
270 |
271 | &.#{$prefix}-padding,
272 | &.#{$prefix}-padding--horizontal,
273 | &.#{$prefix}-padding--right {
274 | padding-right: $marginPlusPadding;
275 | }
276 | }
277 | }
278 | }
279 |
280 | // Classnames for different padding options
281 | @mixin grid-padding($breakpoint) {
282 | @if (map-get($breakpoint, padding) != null) {
283 | $padding: map-get($breakpoint, padding);
284 |
285 | .#{$prefix}-padding {
286 | padding: $padding;
287 | }
288 |
289 | .#{$prefix}-padding--bottom {
290 | padding-bottom: $padding;
291 | }
292 |
293 | .#{$prefix}-padding--left {
294 | padding-left: $padding;
295 | }
296 |
297 | .#{$prefix}-padding--right {
298 | padding-right: $padding;
299 | }
300 |
301 | .#{$prefix}-padding--top {
302 | padding-top: $padding;
303 | }
304 |
305 | .#{$prefix}-padding--horizontal {
306 | padding-left: $padding;
307 | padding-right: $padding;
308 | }
309 |
310 | .#{$prefix}-padding--vertical {
311 | padding-bottom: $padding;
312 | padding-top: $padding;
313 | }
314 | }
315 | }
316 |
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/scss/_sass-list-maps.scss:
--------------------------------------------------------------------------------
1 | /// _
2 | /// | |
3 | /// ___ __ _ ___ ___ ______ _ __ ___ __ _ _ __ ___ ______ _ __ | |_ _ ___
4 | /// / __|/ _` / __/ __|______| '_ ` _ \ / _` | '_ \/ __|______| '_ \| | | | / __|
5 | /// \__ \ (_| \__ \__ \ | | | | | | (_| | |_) \__ \ | |_) | | |_| \__ \
6 | /// |___/\__,_|___/___/ |_| |_| |_|\__,_| .__/|___/ | .__/|_|\__,_|___/
7 | /// | | | |
8 | /// |_| |_|
9 | /// Sass Maps Plus 0.9.2
10 | /// Advanced map and list-map manipulation for all versions of Sass
11 | /// MIT License
12 | /// @author Lu Nelson
13 |
14 | /// Global sort direction: either `asc` or `desc`
15 | /// @access public
16 | /// @group map-lists/map-maps
17 | $maps-sort-dir: "asc";
18 |
19 | /// get value at nested or 'deep' key, per $keys list
20 | /// @access public
21 | /// @group maps
22 | /// @param {Map} $map - map
23 | /// @param {Arglist} $keys - nested keys
24 | /// @return {*}
25 | @function map-get-nested($map, $keys...) {
26 | @if length($map) == 0 {
27 | @return null;
28 | }
29 | @each $key in $keys {
30 | @if type-of($map) != "map" {
31 | @return $map;
32 | }
33 | $map: map-get($map, $key);
34 | }
35 | @return $map;
36 | }
37 |
38 | /// Sort a list-of-maps or map-of-maps, based on value at key(s) in maps
39 | /// @access public
40 | /// @group map-lists/map-maps
41 | /// @param {Map|List} $maps - Map of maps, or List of maps, to sort
42 | /// @param {Arglist} $keys - Chain of keys to the value that will be sorted for
43 | /// @return {Map|List}
44 | /// @require {function} map-get-nested
45 | @function maps-sort($maps, $keys...) {
46 | @if length($keys) == 0 {
47 | @return $maps;
48 | }
49 |
50 | @if length($maps) > 1 {
51 | $less: ();
52 | $equal: ();
53 | $greater: ();
54 |
55 | $map-of-maps: type-of($maps) == "map";
56 |
57 | @if $map-of-maps {
58 | $seed-map: nth(nth($maps, ceil(length($maps) / 2)), 2);
59 |
60 | $seed-value: map-get-nested($seed-map, $keys...);
61 |
62 | // TODO: add code to handle case of non-number values (warn and return $maps)
63 |
64 | @each $key, $map in $maps {
65 | $curr-value: map-get-nested($map, $keys...);
66 |
67 | @if $curr-value == $seed-value {
68 | $equal: map-merge($equal, ($key: $map));
69 | } @else if $curr-value < $seed-value {
70 | @if $maps-sort-dir == "asc" {
71 | $less: map-merge($less, ($key: $map));
72 | } @else {
73 | $greater: map-merge($greater, ($key: $map));
74 | }
75 | } @else {
76 | @if $maps-sort-dir == "asc" {
77 | $greater: map-merge($greater, ($key: $map));
78 | } @else {
79 | $less: map-merge($less, ($key: $map));
80 | }
81 | }
82 | }
83 |
84 | $less: maps-sort($less, $keys...);
85 | $greater: maps-sort($greater, $keys...);
86 |
87 | @return map-merge(map-merge($less, $equal), $greater);
88 | } @else {
89 | $seed-map: nth($maps, ceil(length($maps) / 2));
90 |
91 | $seed-value: map-get-nested($seed-map, $keys...);
92 |
93 | @each $map in $maps {
94 | $curr-value: map-get-nested($map, $keys...);
95 |
96 | @if $curr-value == $seed-value {
97 | $equal: append($equal, $map);
98 | } @else if $curr-value < $seed-value {
99 | @if $maps-sort-dir == "asc" {
100 | $less: append($less, $map);
101 | } @else {
102 | $greater: append($greater, $map);
103 | }
104 | } @else {
105 | @if $maps-sort-dir == "asc" {
106 | $greater: append($greater, $map);
107 | } @else {
108 | $less: append($less, $map);
109 | }
110 | }
111 | }
112 |
113 | $less: maps-sort($less, $keys...);
114 | $greater: maps-sort($greater, $keys...);
115 |
116 | @return join(join($less, $equal), $greater);
117 | }
118 | }
119 |
120 | @return $maps;
121 | }
122 |
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/scss/_utilities.scss:
--------------------------------------------------------------------------------
1 | @import "functions";
2 | @import "values";
3 | @import "variables";
4 |
5 | /// Function returns the value for a given breakpoint.
6 | /// @param {String} $breakpointName Breakpoint name.
7 | /// @return {Length} The breakpoint value in rems.
8 | @function get-breakpoint-value($breakpointName) {
9 | $breakpointValue: map-deep-get(
10 | $breakpointsAndArtboards,
11 | $breakpointName,
12 | "breakpoint"
13 | );
14 |
15 | @return $breakpointValue * 1rem;
16 | }
17 |
18 | /// Returns a calc() expression that represents a fluid width at a given breakpoint.
19 | /// @param {String} $breakpointName A valid breakpoint.
20 | /// @param {Number} $columnSpan The number of columns to span across.
21 | /// @return {Length} A calc() expression representing fluid width.
22 | /// @example scss
23 | /// button {
24 | /// @include media-query('sm') {
25 | /// max-width: get-fluid-size('sm', 1);
26 | /// }
27 | /// }
28 | /// @output css
29 | /// @media screen and (min-width: 20rem) {
30 | /// button {
31 | /// max-width: 25vw;
32 | /// }
33 | /// }
34 | @function get-fluid-size($breakpointName, $columnSpan) {
35 | $breakpoint: map-get($breakpointsAndArtboards, $breakpointName);
36 |
37 | @if ($breakpoint == null or type-of($breakpoint) != "map") {
38 | @error "The provided breakpoint `#{$breakpointName}` is not a valid breakpoint found in breakpoints or extraArtboards in $grid-values. Please double-check your grid configuration.";
39 | }
40 |
41 | $columnTotal: map-get($breakpoint, columns);
42 | $margin: map-get($breakpoint, margin);
43 |
44 | @if ($columnTotal == null or type-of($columnTotal) != "number") {
45 | @error "The provided breakpoint `#{$breakpointName}` needs to have a total number of columns set in $grid-values. Please double-check your grid configuration.";
46 | }
47 |
48 | @if ($columnSpan == null or type-of($columnSpan) != "number") {
49 | @error "The number of columns to span for the breakpoint `#{$breakpointName}` must be a valid number. The provided column span value `#{$columnSpan}` is not a number";
50 | }
51 |
52 | @if ($columnSpan > $columnTotal or $columnSpan <= 0) {
53 | @error "The number of columns to span for the breakpoint `#{$breakpointName}` must be greater than 0 and less than or equal to the total number of columns for this breakpoint. The provided column value `#{$columnSpan}` does not meet this criteria";
54 | }
55 |
56 | $container: 100vw;
57 | // Last breakpoint is a max-width and should be a fixed number
58 | @if is-same-breakpoint($breakpoint, $last) {
59 | $container: map-get($breakpoint, breakpoint) * 1rem;
60 | }
61 |
62 | $multiplier: round-decimal($columnSpan / $columnTotal, 4, floor);
63 |
64 | // For IE, we can't have a 0 in the $fluidWidth calc().
65 | @if ($margin == 0) {
66 | @return $container * $multiplier;
67 | }
68 |
69 | @return calc((#{$container} - #{$margin * 2}) * #{$multiplier});
70 | }
71 |
72 | /// Function gets a calculated rem value for a fixed size.
73 | /// @param {Number} $unitQuantity Fixed nondimensional units.
74 | /// @return {Length} A calculated rem value.
75 | /// @example scss
76 | /// button {
77 | /// @include media-query('sm') {
78 | /// max-width: get-fixed-size(10);
79 | /// }
80 | /// }
81 | /// @output css
82 | /// @media screen and (min-width: 20rem) {
83 | /// button {
84 | /// max-width: 5rem;
85 | /// }
86 | /// }
87 | @function get-fixed-size($unitQuantity) {
88 | // Derive the base unit from the current row height of the grid
89 | $fixedUnit: map-get($grid-values, "rowHeight");
90 |
91 | @if ($fixedUnit == null or type-of($fixedUnit) != "number") {
92 | @error "The rowHeight in $grid-values needs be a valid number. Please check your grid configuration.";
93 | }
94 |
95 | @if ($unitQuantity == null or type-of($unitQuantity) != "number") {
96 | @error "The provided fixed value `#{$unitQuantity}` to get-fixed-size() needs to be a valid number greater than 0.";
97 | }
98 |
99 | @return $unitQuantity * $fixedUnit * 1rem;
100 | }
101 |
102 | /// Utility for declaring mobile-first media queries.
103 | /// @param {String} $breakpointName The name of the breakpoint to set its width value to media query.
104 | @mixin media-query($breakpointName) {
105 | $breakpointValue: get-breakpoint-value($breakpointName);
106 | @if $breakpointValue == map-get($first, breakpoint) {
107 | @content;
108 | } @else {
109 | @media screen and (min-width: #{$breakpointValue}) {
110 | @content;
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/scss/_values.scss:
--------------------------------------------------------------------------------
1 | $grid-values: (
2 | prefix: bootstrap,
3 | breakpoints: (
4 | sm: (
5 | breakpoint: 36,
6 | columns: 12,
7 | gutter: 30px,
8 | margin: 0
9 | ),
10 | xl: (
11 | breakpoint: 100,
12 | columns: 12,
13 | gutter: 30px,
14 | margin: 0
15 | )
16 | ),
17 | extraArtboards: (
18 | md: 51,
19 | lg: 66
20 | ),
21 | rem: 15,
22 | rowHeight: 1,
23 | rows: 30,
24 | paths: null
25 | );
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/scss/_variables.scss:
--------------------------------------------------------------------------------
1 | @import "values";
2 |
3 | $prefix: gridish !default;
4 | @if map-get($grid-values, "prefix") and $prefix == "gridish" {
5 | $prefix: map-get($grid-values, "prefix");
6 | }
7 | $extraBreakpoints: () !default;
8 | $breakpoints: add-padding(map-get($grid-values, "breakpoints"));
9 | $first: nth(nth($breakpoints, 1), 2);
10 | $last: nth(nth($breakpoints, -1), 2);
11 | $includeFlexFallback: false !default;
12 | $rowHeight: map-get($grid-values, "rowHeight");
13 | $rows: map-get($grid-values, "rows");
14 | $extraArtboards: map-get($grid-values, "extraArtboards");
15 | $allBreakpoints: all-breakpoints(
16 | $breakpoints,
17 | $extraBreakpoints,
18 | $first,
19 | $last
20 | );
21 | $breakpointsAndArtboards: all-breakpoints(
22 | $breakpoints,
23 | $extraArtboards,
24 | $first,
25 | $last
26 | );
27 |
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/scss/bootstrap-grid-legacy.scss:
--------------------------------------------------------------------------------
1 | $includeFlexFallback: true;
2 | @import "core.scss";
3 |
4 | @supports (display: grid) {
5 | .#{$prefix}-grid > *,
6 | .#{$prefix}-grid > [class*="#{$prefix}-grid__col--"] {
7 | min-width: initial;
8 | max-width: initial;
9 | width: initial;
10 |
11 | &.#{$prefix}-grid {
12 | display: grid;
13 | }
14 | }
15 |
16 | .#{$prefix}-grid > [class*="#{$prefix}-grid__height--"] {
17 | height: unset;
18 | max-height: unset;
19 | min-height: initial;
20 | }
21 | }
22 |
23 | .#{$prefix}-grid > script {
24 | display: none;
25 | }
26 |
--------------------------------------------------------------------------------
/examples/bootstrap/css-gridish/scss/bootstrap-grid.scss:
--------------------------------------------------------------------------------
1 | @import "core.scss";
2 |
--------------------------------------------------------------------------------
/examples/bootstrap/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
32 |
33 |
34 |
35 |
36 |
CSS Gridish
37 |
Bootstrap Example
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
Learn more about
46 | CSS Gridish.
47 |
48 |
Also check out our examples of CSS Gridish making grid code for
49 | Carbon and
50 | Material.
51 |
52 |
53 |
54 |
79 |
80 |
--------------------------------------------------------------------------------
/examples/bootstrap/intro.md:
--------------------------------------------------------------------------------
1 | # Bootstrap Design Grid
2 |
3 | An example of [CSS Gridish](../../../README.md) generating CSS Grid code, fallback flexbox code, dev documentation, and Sketch files based on the [Bootstrap v4 grid.](https://github.com/twbs/bootstrap/blob/v4-dev/scss/_variables.scss#L168-174)
4 |
--------------------------------------------------------------------------------
/examples/bootstrap/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css-gridish-example-carbon",
3 | "version": "0.0.1",
4 | "engines": {
5 | "node": ">=8.2.0"
6 | },
7 | "repository": {
8 | "type": "git",
9 | "url": "git@ibm.com:ibm/css-gridish.git"
10 | },
11 | "author": "James Y. Rauhut ",
12 | "license": "Apache-2.0",
13 | "scripts": {
14 | "build": "node ../../bin/index.js",
15 | "test": "true"
16 | },
17 | "dependencies": {}
18 | }
19 |
--------------------------------------------------------------------------------
/examples/bootstrap/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examples/carbon/README.md:
--------------------------------------------------------------------------------
1 | # Carbon Design Grid
2 |
3 | [View a random layout with this grid.](https://ibm.github.io/css-gridish/examples/carbon/index.html)
4 |
5 | An example of [CSS Gridish](../../README.md) generating CSS Grid code, fallback flexbox code, dev documentation, and Sketch files based on the [Carbon Design System grid.](http://carbondesignsystem.com/style/grid/design)
6 |
7 | Check out everything CSS Gridish made based off of the [config file](./css-gridish.json) in the [css-gridish folder.](./css-gridish/)
8 |
--------------------------------------------------------------------------------
/examples/carbon/css-gridish.json:
--------------------------------------------------------------------------------
1 | {
2 | "prefix": "bx",
3 | "breakpoints": {
4 | "sm": {
5 | "breakpoint": 20,
6 | "columns": 12,
7 | "gutter": "1.250rem",
8 | "margin": "5vw"
9 | },
10 | "xxl": {
11 | "breakpoint": 100,
12 | "columns": 12,
13 | "gutter": "1.250rem",
14 | "margin": "5vw"
15 | }
16 | },
17 | "extraArtboards": {
18 | "md": 48,
19 | "lg": 62,
20 | "xl": 75
21 | },
22 | "rem": 16,
23 | "rowHeight": 0.5,
24 | "rows": 30,
25 | "paths": {
26 | "intro": "intro.md"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/bx-grid.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/examples/carbon/css-gridish/bx-grid.sketch
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/css/bx-grid-legacy.min.css:
--------------------------------------------------------------------------------
1 | html{font-size:16px}body{margin:0}.bx-container{box-sizing:border-box;margin-left:auto;margin-right:auto;max-width:100rem;overflow-x:hidden;width:100vw}.bx-container--left{margin-left:0}.bx-container--right{margin-right:0}.bx-grid{align-items:flex-start;box-sizing:border-box;display:flex;display:grid;flex-wrap:wrap;position:relative;grid-auto-rows:minmax(.5rem,min-content);grid-template-columns:repeat(auto-fill,calc((100vw - 10vw) * .0833))}.bx-grid>*{box-sizing:border-box;width:100%;grid-column:span 12}.bx-grid>* :last-child,.bx-grid>* :last-child>:last-child,.bx-grid>* :last-child>:last-child>:last-child{margin-bottom:0}[class*=bx-padding]{box-sizing:border-box}@supports (display:grid){.bx-grid{align-items:unset}.bx-grid>*{width:initial;height:100%}:root{--bx-height-1:0.5rem;--bx-height-2:1rem;--bx-height-3:1.5rem;--bx-height-4:2rem;--bx-height-5:2.5rem;--bx-height-6:3rem;--bx-height-7:3.5rem;--bx-height-8:4rem;--bx-height-9:4.5rem;--bx-height-10:5rem;--bx-height-11:5.5rem;--bx-height-12:6rem;--bx-height-13:6.5rem;--bx-height-14:7rem;--bx-height-15:7.5rem;--bx-height-16:8rem;--bx-height-17:8.5rem;--bx-height-18:9rem;--bx-height-19:9.5rem;--bx-height-20:10rem;--bx-height-21:10.5rem;--bx-height-22:11rem;--bx-height-23:11.5rem;--bx-height-24:12rem;--bx-height-25:12.5rem;--bx-height-26:13rem;--bx-height-27:13.5rem;--bx-height-28:14rem;--bx-height-29:14.5rem}}.bx-grid__height--sm--0{height:0;min-height:0}.bx-grid__height--sm--1{grid-row:span 1;height:.5rem;min-height:.5rem}.bx-grid__height--sm--2{grid-row:span 2;height:1rem;min-height:1rem}.bx-grid__height--sm--3{grid-row:span 3;height:1.5rem;min-height:1.5rem}.bx-grid__height--sm--4{grid-row:span 4;height:2rem;min-height:2rem}.bx-grid__height--sm--5{grid-row:span 5;height:2.5rem;min-height:2.5rem}.bx-grid__height--sm--6{grid-row:span 6;height:3rem;min-height:3rem}.bx-grid__height--sm--7{grid-row:span 7;height:3.5rem;min-height:3.5rem}.bx-grid__height--sm--8{grid-row:span 8;height:4rem;min-height:4rem}.bx-grid__height--sm--9{grid-row:span 9;height:4.5rem;min-height:4.5rem}.bx-grid__height--sm--10{grid-row:span 10;height:5rem;min-height:5rem}.bx-grid__height--sm--11{grid-row:span 11;height:5.5rem;min-height:5.5rem}.bx-grid__height--sm--12{grid-row:span 12;height:6rem;min-height:6rem}.bx-grid__height--sm--13{grid-row:span 13;height:6.5rem;min-height:6.5rem}.bx-grid__height--sm--14{grid-row:span 14;height:7rem;min-height:7rem}.bx-grid__height--sm--15{grid-row:span 15;height:7.5rem;min-height:7.5rem}.bx-grid__height--sm--16{grid-row:span 16;height:8rem;min-height:8rem}.bx-grid__height--sm--17{grid-row:span 17;height:8.5rem;min-height:8.5rem}.bx-grid__height--sm--18{grid-row:span 18;height:9rem;min-height:9rem}.bx-grid__height--sm--19{grid-row:span 19;height:9.5rem;min-height:9.5rem}.bx-grid__height--sm--20{grid-row:span 20;height:10rem;min-height:10rem}.bx-grid__height--sm--21{grid-row:span 21;height:10.5rem;min-height:10.5rem}.bx-grid__height--sm--22{grid-row:span 22;height:11rem;min-height:11rem}.bx-grid__height--sm--23{grid-row:span 23;height:11.5rem;min-height:11.5rem}.bx-grid__height--sm--24{grid-row:span 24;height:12rem;min-height:12rem}.bx-grid__height--sm--25{grid-row:span 25;height:12.5rem;min-height:12.5rem}.bx-grid__height--sm--26{grid-row:span 26;height:13rem;min-height:13rem}.bx-grid__height--sm--27{grid-row:span 27;height:13.5rem;min-height:13.5rem}.bx-grid__height--sm--28{grid-row:span 28;height:14rem;min-height:14rem}.bx-grid__height--sm--29{grid-row:span 29;height:14.5rem;min-height:14.5rem}[class*=bx-grid__col--sm--]{display:block}.bx-grid__col--sm--0,.bx-grid__col--sm--0--only{display:none}.bx-padding{padding:.625rem}.bx-padding--bottom{padding-bottom:.625rem}.bx-padding--left{padding-left:.625rem}.bx-padding--right{padding-right:.625rem}.bx-padding--top{padding-top:.625rem}.bx-padding--horizontal{padding-left:.625rem;padding-right:.625rem}.bx-padding--vertical{padding-bottom:.625rem;padding-top:.625rem}.bx-grid.bx-grid--fixed-columns{grid-template-columns:repeat(auto-fill,1.66667rem)}.bx-grid.bx-grid--fluid-rows{grid-auto-rows:calc((100vw - 10vw) * .0833)}.bx-grid__col--sm--1{max-width:calc((100rem - 10vw) * .0833);width:calc((100vw - 10vw) * .0833);grid-column:span 1}.bx-grid__col--sm--1.bx-grid>:not([class*=bx-grid__col]){grid-column:span 1}.bx-grid--fluid-rows>.bx-grid__height--sm--1{grid-row:span 1;height:calc((100vw - 10vw) * .0833);min-height:calc((100vw - 10vw) * .0833);max-height:calc((100rem - 10vw) * .0833)}.bx-grid__col--sm--2{max-width:calc((100rem - 10vw) * .1666);width:calc((100vw - 10vw) * .1666);grid-column:span 2}.bx-grid__col--sm--2.bx-grid>:not([class*=bx-grid__col]){grid-column:span 2}.bx-grid--fluid-rows>.bx-grid__height--sm--2{grid-row:span 2;height:calc((100vw - 10vw) * .1666);min-height:calc((100vw - 10vw) * .1666);max-height:calc((100rem - 10vw) * .1666)}.bx-grid__col--sm--3{max-width:calc((100rem - 10vw) * .25);width:calc((100vw - 10vw) * .25);grid-column:span 3}.bx-grid__col--sm--3.bx-grid>:not([class*=bx-grid__col]){grid-column:span 3}.bx-grid--fluid-rows>.bx-grid__height--sm--3{grid-row:span 3;height:calc((100vw - 10vw) * .25);min-height:calc((100vw - 10vw) * .25);max-height:calc((100rem - 10vw) * .25)}.bx-grid__col--sm--4{max-width:calc((100rem - 10vw) * .3333);width:calc((100vw - 10vw) * .3333);grid-column:span 4}.bx-grid__col--sm--4.bx-grid>:not([class*=bx-grid__col]){grid-column:span 4}.bx-grid--fluid-rows>.bx-grid__height--sm--4{grid-row:span 4;height:calc((100vw - 10vw) * .3333);min-height:calc((100vw - 10vw) * .3333);max-height:calc((100rem - 10vw) * .3333)}.bx-grid__col--sm--5{max-width:calc((100rem - 10vw) * .4166);width:calc((100vw - 10vw) * .4166);grid-column:span 5}.bx-grid__col--sm--5.bx-grid>:not([class*=bx-grid__col]){grid-column:span 5}.bx-grid--fluid-rows>.bx-grid__height--sm--5{grid-row:span 5;height:calc((100vw - 10vw) * .4166);min-height:calc((100vw - 10vw) * .4166);max-height:calc((100rem - 10vw) * .4166)}.bx-grid__col--sm--6{max-width:calc((100rem - 10vw) * .5);width:calc((100vw - 10vw) * .5);grid-column:span 6}.bx-grid__col--sm--6.bx-grid>:not([class*=bx-grid__col]){grid-column:span 6}.bx-grid--fluid-rows>.bx-grid__height--sm--6{grid-row:span 6;height:calc((100vw - 10vw) * .5);min-height:calc((100vw - 10vw) * .5);max-height:calc((100rem - 10vw) * .5)}.bx-grid__col--sm--7{max-width:calc((100rem - 10vw) * .5833);width:calc((100vw - 10vw) * .5833);grid-column:span 7}.bx-grid__col--sm--7.bx-grid>:not([class*=bx-grid__col]){grid-column:span 7}.bx-grid--fluid-rows>.bx-grid__height--sm--7{grid-row:span 7;height:calc((100vw - 10vw) * .5833);min-height:calc((100vw - 10vw) * .5833);max-height:calc((100rem - 10vw) * .5833)}.bx-grid__col--sm--8{max-width:calc((100rem - 10vw) * .6666);width:calc((100vw - 10vw) * .6666);grid-column:span 8}.bx-grid__col--sm--8.bx-grid>:not([class*=bx-grid__col]){grid-column:span 8}.bx-grid--fluid-rows>.bx-grid__height--sm--8{grid-row:span 8;height:calc((100vw - 10vw) * .6666);min-height:calc((100vw - 10vw) * .6666);max-height:calc((100rem - 10vw) * .6666)}.bx-grid__col--sm--9{max-width:calc((100rem - 10vw) * .75);width:calc((100vw - 10vw) * .75);grid-column:span 9}.bx-grid__col--sm--9.bx-grid>:not([class*=bx-grid__col]){grid-column:span 9}.bx-grid--fluid-rows>.bx-grid__height--sm--9{grid-row:span 9;height:calc((100vw - 10vw) * .75);min-height:calc((100vw - 10vw) * .75);max-height:calc((100rem - 10vw) * .75)}.bx-grid__col--sm--10{max-width:calc((100rem - 10vw) * .8333);width:calc((100vw - 10vw) * .8333);grid-column:span 10}.bx-grid__col--sm--10.bx-grid>:not([class*=bx-grid__col]){grid-column:span 10}.bx-grid--fluid-rows>.bx-grid__height--sm--10{grid-row:span 10;height:calc((100vw - 10vw) * .8333);min-height:calc((100vw - 10vw) * .8333);max-height:calc((100rem - 10vw) * .8333)}.bx-grid__col--sm--11{max-width:calc((100rem - 10vw) * .9166);width:calc((100vw - 10vw) * .9166);grid-column:span 11}.bx-grid__col--sm--11.bx-grid>:not([class*=bx-grid__col]){grid-column:span 11}.bx-grid--fluid-rows>.bx-grid__height--sm--11{grid-row:span 11;height:calc((100vw - 10vw) * .9166);min-height:calc((100vw - 10vw) * .9166);max-height:calc((100rem - 10vw) * .9166)}.bx-grid__col--sm--12{max-width:calc((100rem - 10vw) * 1);width:calc((100vw - 10vw) * 1);grid-column:span 12}.bx-grid__col--sm--12.bx-grid>:not([class*=bx-grid__col]){grid-column:span 12}.bx-grid--fluid-rows>.bx-grid__height--sm--12{grid-row:span 12;height:calc((100vw - 10vw) * 1);min-height:calc((100vw - 10vw) * 1);max-height:calc((100rem - 10vw) * 1)}@supports (display:grid){.bx-container{margin-left:auto;margin-right:auto;padding-left:5vw;padding-right:5vw}.bx-container--left{margin-left:0}.bx-container--right{margin-right:0}.bx-container__bleed--sm,.bx-container__bleed--sm--left,.bx-container__break--sm,.bx-container__break--sm--left{margin-left:-5vw}.bx-container__bleed--sm,.bx-container__bleed--sm--right,.bx-container__break--sm,.bx-container__break--sm--right{margin-right:-5vw}.bx-container__bleed--sm,.bx-container__bleed--sm--left{padding-left:5vw}.bx-container__bleed--sm--left.bx-padding,.bx-container__bleed--sm--left.bx-padding--horizontal,.bx-container__bleed--sm--left.bx-padding--left,.bx-container__bleed--sm.bx-padding,.bx-container__bleed--sm.bx-padding--horizontal,.bx-container__bleed--sm.bx-padding--left{padding-left:calc(5vw + .625rem)}.bx-container__bleed--sm,.bx-container__bleed--sm--right{padding-right:5vw}.bx-container__bleed--sm--right.bx-padding,.bx-container__bleed--sm--right.bx-padding--horizontal,.bx-container__bleed--sm--right.bx-padding--right,.bx-container__bleed--sm.bx-padding,.bx-container__bleed--sm.bx-padding--horizontal,.bx-container__bleed--sm.bx-padding--right{padding-right:calc(5vw + .625rem)}}@media screen and (min-width:100rem){.bx-grid__col--sm--0--only,[class*=bx-grid__col--xxl--]{display:block}.bx-grid__col--xxl--0,.bx-grid__col--xxl--0--only{display:none}.bx-padding{padding:.625rem}.bx-padding--bottom{padding-bottom:.625rem}.bx-padding--left{padding-left:.625rem}.bx-padding--right{padding-right:.625rem}.bx-padding--top{padding-top:.625rem}.bx-padding--horizontal{padding-left:.625rem;padding-right:.625rem}.bx-padding--vertical{padding-bottom:.625rem;padding-top:.625rem}.bx-grid{grid-template-columns:repeat(auto-fill,calc((100rem - 10vw) * .0833))}.bx-grid.bx-grid--fixed-columns{grid-template-columns:repeat(auto-fill,8.33333rem)}.bx-grid.bx-grid--fluid-rows{grid-auto-rows:calc((100rem - 10vw) * .0833)}[class*=bx-grid__col--]{min-width:0}@supports (display:grid){.bx-container{margin-left:auto;margin-right:auto;padding-left:5vw;padding-right:5vw}.bx-container--left{margin-left:0}.bx-container--right{margin-right:0}.bx-container__bleed--sm,.bx-container__bleed--sm--left,.bx-container__break--sm,.bx-container__break--sm--left{margin-left:-5vw}.bx-container__bleed--sm,.bx-container__bleed--sm--right,.bx-container__break--sm,.bx-container__break--sm--right{margin-right:-5vw}.bx-container__bleed--sm,.bx-container__bleed--sm--left{padding-left:5vw}.bx-container__bleed--sm--left.bx-padding,.bx-container__bleed--sm--left.bx-padding--horizontal,.bx-container__bleed--sm--left.bx-padding--left,.bx-container__bleed--sm.bx-padding,.bx-container__bleed--sm.bx-padding--horizontal,.bx-container__bleed--sm.bx-padding--left{padding-left:calc(5vw + .625rem)}.bx-container__bleed--sm,.bx-container__bleed--sm--right{padding-right:5vw}.bx-container__bleed--sm--right.bx-padding,.bx-container__bleed--sm--right.bx-padding--horizontal,.bx-container__bleed--sm--right.bx-padding--right,.bx-container__bleed--sm.bx-padding,.bx-container__bleed--sm.bx-padding--horizontal,.bx-container__bleed--sm.bx-padding--right{padding-right:calc(5vw + .625rem)}}}@supports (display:grid){.bx-grid>*,.bx-grid>[class*=bx-grid__col--]{min-width:initial;max-width:initial;width:initial}.bx-grid>.bx-grid,.bx-grid>[class*=bx-grid__col--].bx-grid{display:grid}.bx-grid>[class*=bx-grid__height--]{height:unset;max-height:unset;min-height:initial}}.bx-grid>script{display:none}
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/css/bx-grid.min.css:
--------------------------------------------------------------------------------
1 | html{font-size:16px}body{margin:0}.bx-grid{align-items:flex-start;box-sizing:border-box;display:grid;flex-wrap:wrap;position:relative;grid-auto-rows:minmax(.5rem,min-content);grid-template-columns:repeat(auto-fill,calc((100vw - 10vw) * .0833))}.bx-grid>*{box-sizing:border-box;grid-column:span 12}.bx-grid>* :last-child,.bx-grid>* :last-child>:last-child,.bx-grid>* :last-child>:last-child>:last-child{margin-bottom:0}[class*=bx-padding]{box-sizing:border-box}@supports (display:grid){.bx-grid>*{height:100%}}:root{--bx-height-1:0.5rem;--bx-height-2:1rem;--bx-height-3:1.5rem;--bx-height-4:2rem;--bx-height-5:2.5rem;--bx-height-6:3rem;--bx-height-7:3.5rem;--bx-height-8:4rem;--bx-height-9:4.5rem;--bx-height-10:5rem;--bx-height-11:5.5rem;--bx-height-12:6rem;--bx-height-13:6.5rem;--bx-height-14:7rem;--bx-height-15:7.5rem;--bx-height-16:8rem;--bx-height-17:8.5rem;--bx-height-18:9rem;--bx-height-19:9.5rem;--bx-height-20:10rem;--bx-height-21:10.5rem;--bx-height-22:11rem;--bx-height-23:11.5rem;--bx-height-24:12rem;--bx-height-25:12.5rem;--bx-height-26:13rem;--bx-height-27:13.5rem;--bx-height-28:14rem;--bx-height-29:14.5rem}.bx-grid__height--sm--0{height:0;min-height:0}.bx-grid__height--sm--1{grid-row:span 1}.bx-grid__height--sm--2{grid-row:span 2}.bx-grid__height--sm--3{grid-row:span 3}.bx-grid__height--sm--4{grid-row:span 4}.bx-grid__height--sm--5{grid-row:span 5}.bx-grid__height--sm--6{grid-row:span 6}.bx-grid__height--sm--7{grid-row:span 7}.bx-grid__height--sm--8{grid-row:span 8}.bx-grid__height--sm--9{grid-row:span 9}.bx-grid__height--sm--10{grid-row:span 10}.bx-grid__height--sm--11{grid-row:span 11}.bx-grid__height--sm--12{grid-row:span 12}.bx-grid__height--sm--13{grid-row:span 13}.bx-grid__height--sm--14{grid-row:span 14}.bx-grid__height--sm--15{grid-row:span 15}.bx-grid__height--sm--16{grid-row:span 16}.bx-grid__height--sm--17{grid-row:span 17}.bx-grid__height--sm--18{grid-row:span 18}.bx-grid__height--sm--19{grid-row:span 19}.bx-grid__height--sm--20{grid-row:span 20}.bx-grid__height--sm--21{grid-row:span 21}.bx-grid__height--sm--22{grid-row:span 22}.bx-grid__height--sm--23{grid-row:span 23}.bx-grid__height--sm--24{grid-row:span 24}.bx-grid__height--sm--25{grid-row:span 25}.bx-grid__height--sm--26{grid-row:span 26}.bx-grid__height--sm--27{grid-row:span 27}.bx-grid__height--sm--28{grid-row:span 28}.bx-grid__height--sm--29{grid-row:span 29}[class*=bx-grid__col--sm--]{display:block}.bx-grid__col--sm--0,.bx-grid__col--sm--0--only{display:none}.bx-padding{padding:.625rem}.bx-padding--bottom{padding-bottom:.625rem}.bx-padding--left{padding-left:.625rem}.bx-padding--right{padding-right:.625rem}.bx-padding--top{padding-top:.625rem}.bx-padding--horizontal{padding-left:.625rem;padding-right:.625rem}.bx-padding--vertical{padding-bottom:.625rem;padding-top:.625rem}.bx-grid.bx-grid--fixed-columns{grid-template-columns:repeat(auto-fill,1.66667rem)}.bx-grid.bx-grid--fluid-rows{grid-auto-rows:calc((100vw - 10vw) * .0833)}.bx-grid__col--sm--1,.bx-grid__col--sm--1.bx-grid>:not([class*=bx-grid__col]){grid-column:span 1}.bx-grid--fluid-rows>.bx-grid__height--sm--1{grid-row:span 1}.bx-grid__col--sm--2,.bx-grid__col--sm--2.bx-grid>:not([class*=bx-grid__col]){grid-column:span 2}.bx-grid--fluid-rows>.bx-grid__height--sm--2{grid-row:span 2}.bx-grid__col--sm--3,.bx-grid__col--sm--3.bx-grid>:not([class*=bx-grid__col]){grid-column:span 3}.bx-grid--fluid-rows>.bx-grid__height--sm--3{grid-row:span 3}.bx-grid__col--sm--4,.bx-grid__col--sm--4.bx-grid>:not([class*=bx-grid__col]){grid-column:span 4}.bx-grid--fluid-rows>.bx-grid__height--sm--4{grid-row:span 4}.bx-grid__col--sm--5,.bx-grid__col--sm--5.bx-grid>:not([class*=bx-grid__col]){grid-column:span 5}.bx-grid--fluid-rows>.bx-grid__height--sm--5{grid-row:span 5}.bx-grid__col--sm--6,.bx-grid__col--sm--6.bx-grid>:not([class*=bx-grid__col]){grid-column:span 6}.bx-grid--fluid-rows>.bx-grid__height--sm--6{grid-row:span 6}.bx-grid__col--sm--7,.bx-grid__col--sm--7.bx-grid>:not([class*=bx-grid__col]){grid-column:span 7}.bx-grid--fluid-rows>.bx-grid__height--sm--7{grid-row:span 7}.bx-grid__col--sm--8,.bx-grid__col--sm--8.bx-grid>:not([class*=bx-grid__col]){grid-column:span 8}.bx-grid--fluid-rows>.bx-grid__height--sm--8{grid-row:span 8}.bx-grid__col--sm--9,.bx-grid__col--sm--9.bx-grid>:not([class*=bx-grid__col]){grid-column:span 9}.bx-grid--fluid-rows>.bx-grid__height--sm--9{grid-row:span 9}.bx-grid__col--sm--10,.bx-grid__col--sm--10.bx-grid>:not([class*=bx-grid__col]){grid-column:span 10}.bx-grid--fluid-rows>.bx-grid__height--sm--10{grid-row:span 10}.bx-grid__col--sm--11,.bx-grid__col--sm--11.bx-grid>:not([class*=bx-grid__col]){grid-column:span 11}.bx-grid--fluid-rows>.bx-grid__height--sm--11{grid-row:span 11}.bx-grid__col--sm--12,.bx-grid__col--sm--12.bx-grid>:not([class*=bx-grid__col]){grid-column:span 12}.bx-grid--fluid-rows>.bx-grid__height--sm--12{grid-row:span 12}.bx-container{box-sizing:border-box;max-width:100rem;overflow-x:hidden;width:100vw;margin-left:auto;margin-right:auto;padding-left:5vw;padding-right:5vw}.bx-container--left{margin-left:0}.bx-container--right{margin-right:0}.bx-container__bleed--sm,.bx-container__bleed--sm--left,.bx-container__break--sm,.bx-container__break--sm--left{margin-left:-5vw}.bx-container__bleed--sm,.bx-container__bleed--sm--right,.bx-container__break--sm,.bx-container__break--sm--right{margin-right:-5vw}.bx-container__bleed--sm,.bx-container__bleed--sm--left{padding-left:5vw}.bx-container__bleed--sm--left.bx-padding,.bx-container__bleed--sm--left.bx-padding--horizontal,.bx-container__bleed--sm--left.bx-padding--left,.bx-container__bleed--sm.bx-padding,.bx-container__bleed--sm.bx-padding--horizontal,.bx-container__bleed--sm.bx-padding--left{padding-left:calc(5vw + .625rem)}.bx-container__bleed--sm,.bx-container__bleed--sm--right{padding-right:5vw}.bx-container__bleed--sm--right.bx-padding,.bx-container__bleed--sm--right.bx-padding--horizontal,.bx-container__bleed--sm--right.bx-padding--right,.bx-container__bleed--sm.bx-padding,.bx-container__bleed--sm.bx-padding--horizontal,.bx-container__bleed--sm.bx-padding--right{padding-right:calc(5vw + .625rem)}@media screen and (min-width:100rem){.bx-grid__col--sm--0--only,[class*=bx-grid__col--xxl--]{display:block}.bx-grid__col--xxl--0,.bx-grid__col--xxl--0--only{display:none}.bx-padding{padding:.625rem}.bx-padding--bottom{padding-bottom:.625rem}.bx-padding--left{padding-left:.625rem}.bx-padding--right{padding-right:.625rem}.bx-padding--top{padding-top:.625rem}.bx-padding--horizontal{padding-left:.625rem;padding-right:.625rem}.bx-padding--vertical{padding-bottom:.625rem;padding-top:.625rem}.bx-grid{grid-template-columns:repeat(auto-fill,calc((100rem - 10vw) * .0833))}.bx-grid.bx-grid--fixed-columns{grid-template-columns:repeat(auto-fill,8.33333rem)}.bx-grid.bx-grid--fluid-rows{grid-auto-rows:calc((100rem - 10vw) * .0833)}.bx-container{margin-left:auto;margin-right:auto;padding-left:5vw;padding-right:5vw}.bx-container--left{margin-left:0}.bx-container--right{margin-right:0}.bx-container__bleed--sm,.bx-container__bleed--sm--left,.bx-container__break--sm,.bx-container__break--sm--left{margin-left:-5vw}.bx-container__bleed--sm,.bx-container__bleed--sm--right,.bx-container__break--sm,.bx-container__break--sm--right{margin-right:-5vw}.bx-container__bleed--sm,.bx-container__bleed--sm--left{padding-left:5vw}.bx-container__bleed--sm--left.bx-padding,.bx-container__bleed--sm--left.bx-padding--horizontal,.bx-container__bleed--sm--left.bx-padding--left,.bx-container__bleed--sm.bx-padding,.bx-container__bleed--sm.bx-padding--horizontal,.bx-container__bleed--sm.bx-padding--left{padding-left:calc(5vw + .625rem)}.bx-container__bleed--sm,.bx-container__bleed--sm--right{padding-right:5vw}.bx-container__bleed--sm--right.bx-padding,.bx-container__bleed--sm--right.bx-padding--horizontal,.bx-container__bleed--sm--right.bx-padding--right,.bx-container__bleed--sm.bx-padding,.bx-container__bleed--sm.bx-padding--horizontal,.bx-container__bleed--sm.bx-padding--right{padding-right:calc(5vw + .625rem)}}
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/scss/_core.scss:
--------------------------------------------------------------------------------
1 | @import "functions.scss";
2 | @import "mixins.scss";
3 | @import "variables.scss";
4 | @import "utilities.scss";
5 |
6 | html {
7 | font-size: map-get($grid-values, "rem") * 1px;
8 | }
9 |
10 | body {
11 | margin: 0;
12 | }
13 |
14 | .#{$prefix}-container {
15 | box-sizing: border-box;
16 | margin-left: auto;
17 | margin-right: auto;
18 | max-width: #{map-get($last, breakpoint)}rem;
19 | overflow-x: hidden;
20 | width: 100vw;
21 | }
22 |
23 | .#{$prefix}-container--left {
24 | margin-left: 0;
25 | }
26 |
27 | .#{$prefix}-container--right {
28 | margin-right: 0;
29 | }
30 |
31 | .#{$prefix}-grid {
32 | align-items: flex-start;
33 | box-sizing: border-box;
34 | @if $includeFlexFallback {
35 | display: flex;
36 | }
37 | display: grid;
38 | flex-wrap: wrap;
39 | position: relative;
40 |
41 | > * {
42 | box-sizing: border-box;
43 |
44 | :last-child,
45 | :last-child > :last-child,
46 | :last-child > :last-child > :last-child {
47 | margin-bottom: 0;
48 | }
49 | }
50 | }
51 |
52 | [class*="#{$prefix}-padding"] {
53 | box-sizing: border-box;
54 | }
55 |
56 | // Rules needed in legacy, but needed to change in CSS Grid
57 | @if $includeFlexFallback {
58 | .#{$prefix}-grid > * {
59 | width: 100%;
60 | }
61 |
62 | @supports (display: grid) {
63 | .#{$prefix}-grid {
64 | align-items: unset;
65 | }
66 |
67 | .#{$prefix}-grid > * {
68 | width: initial;
69 | }
70 | }
71 | }
72 |
73 | // Rules not needed in legacy, but needed in CSS Grid
74 | @supports (display: grid) {
75 | .#{$prefix}-grid > * {
76 | height: 100%;
77 | }
78 | }
79 |
80 | @include grid-legacy-wrapper($includeFlexFallback) {
81 | :root {
82 | @include grid-heights-fixed($rows);
83 | }
84 | }
85 |
86 | @each $name, $breakpoint in $allBreakpoints {
87 | @include media-query($name) {
88 | @if is-same-breakpoint($breakpoint, $last) == false {
89 | @include grid-legacy-heights($name);
90 | }
91 | @include grid-legacy-zeros($breakpoint, $name);
92 | @include grid-padding($breakpoint);
93 | @include grid($breakpoint, $name);
94 | @include grid-legacy-columns($breakpoint, $name);
95 |
96 | // Wrap all bleed/break classes and css variables in a CSS Grid support query
97 | @include grid-legacy-wrapper($includeFlexFallback) {
98 | @include grid-margin($breakpoint, $name);
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/scss/_functions.scss:
--------------------------------------------------------------------------------
1 | @import "sass-list-maps";
2 |
3 | // Transform the gutter property into a padding property for web
4 | @function add-padding($breakpoints) {
5 | $cleanBreakpoints: ();
6 | @each $name, $breakpoint in $breakpoints {
7 | $cleanBreakpoints: map-merge(
8 | $cleanBreakpoints,
9 | (
10 | $name:
11 | map-merge($breakpoint, (padding: map-get($breakpoint, gutter) / 2))
12 | )
13 | );
14 | }
15 |
16 | @return $cleanBreakpoints;
17 | }
18 |
19 | // Merge standard and custom breakpoints into list
20 | @function all-breakpoints($breakpoints, $extraBreakpoints, $first, $last) {
21 | $allBreakpoints: $breakpoints;
22 | @each $currentBreakpoint in $extraBreakpoints {
23 | $extraBreakpointName: nth($currentBreakpoint, 1);
24 | $extraBreakpointWidth: nth($currentBreakpoint, 2);
25 | $found: false;
26 | $match: null;
27 | @each $majorBreakpoint in $breakpoints {
28 | @if $found == false {
29 | @if map-get(nth($majorBreakpoint, 2), breakpoint) >
30 | $extraBreakpointWidth
31 | {
32 | $found: true;
33 | } @else {
34 | $match: $majorBreakpoint;
35 | }
36 | }
37 | }
38 | @if $extraBreakpointWidth > map-get($last, breakpoint) {
39 | $match: (
40 | last,
41 | $last
42 | );
43 | }
44 | @if $extraBreakpointWidth < map-get($first, breakpoint) {
45 | $match: (
46 | first,
47 | $first
48 | );
49 | }
50 |
51 | $newBreakpoint: map-merge(
52 | nth($match, 2),
53 | (breakpoint: $extraBreakpointWidth)
54 | );
55 | $currentBreakpoint: (
56 | $extraBreakpointName:
57 | map-merge(nth($match, 2), (breakpoint: $extraBreakpointWidth))
58 | );
59 | $allBreakpoints: map-merge($allBreakpoints, $currentBreakpoint);
60 | }
61 |
62 | @return maps-sort($allBreakpoints, breakpoint);
63 | }
64 |
65 | @function is-same-breakpoint($a, $b) {
66 | @return map-get($a, breakpoint) == map-get($b, breakpoint);
67 | }
68 |
69 | /// Traverse maps and retrieve deeply nested values: https://css-tricks.com/snippets/sass/deep-getset-maps/
70 | /// @author Hugo Giraudel
71 | /// @param {Map} $map A sass map and any number of keys.
72 | /// @param {*} $keys Nested values.
73 | /// @return Nested values or nested map.
74 | @function map-deep-get($map, $keys...) {
75 | @each $key in $keys {
76 | $map: map-get($map, $key);
77 | }
78 | @return $map;
79 | }
80 |
81 | // _decimal.scss | MIT License | gist.github.com/terkel/4373420
82 | @function round-decimal($number, $digits: 0, $mode: round) {
83 | $n: 1;
84 | // $number must be a number
85 | @if type-of($number) != number {
86 | @warn "#{ $number } is not a number.";
87 | @return $number;
88 | }
89 | // $digits must be a unitless number
90 | @if type-of($digits) != number {
91 | @warn "#{ $digits } is not a number.";
92 | @return $number;
93 | } @else if not unitless($digits) {
94 | @warn "#{ $digits } has a unit.";
95 | @return $number;
96 | }
97 | @for $i from 1 through $digits {
98 | $n: $n * 10;
99 | }
100 | @if $mode == round {
101 | @return round($number * $n) / $n;
102 | } @else if $mode == ceil {
103 | @return ceil($number * $n) / $n;
104 | } @else if $mode == floor {
105 | @return floor($number * $n) / $n;
106 | } @else {
107 | @warn "#{ $mode } is undefined keyword.";
108 | @return $number;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Set the width of a grid’s column
2 | @mixin grid($breakpoint, $breakpointName) {
3 | @if (map-get($breakpoint, columns) != null) {
4 | $columnSize: get-fluid-size($breakpointName, 1);
5 |
6 | .#{$prefix}-grid {
7 | @if is-same-breakpoint($breakpoint, $first) {
8 | grid-auto-rows: minmax($rowHeight * 1rem, min-content);
9 | }
10 | grid-template-columns: repeat(auto-fill, $columnSize);
11 |
12 | &.#{$prefix}-grid--fixed-columns {
13 | grid-template-columns: repeat(
14 | auto-fill,
15 | map-get($breakpoint, breakpoint) *
16 | 1rem /
17 | map-get($breakpoint, columns)
18 | );
19 | }
20 |
21 | &.#{$prefix}-grid--fluid-rows {
22 | grid-auto-rows: $columnSize;
23 | }
24 |
25 | @if is-same-breakpoint($breakpoint, $last) == false {
26 | > * {
27 | grid-column: span #{map-get($breakpoint, columns)};
28 | }
29 | }
30 | }
31 | }
32 | }
33 |
34 | // Generate variables for commonly used rows
35 | @mixin grid-heights-fixed($rows) {
36 | @for $i from 1 to $rows {
37 | --#{$prefix}-height-#{$i}: get-fixed-size($i);
38 | }
39 | }
40 |
41 | // Set the width of a grid’s column for legacy grid
42 | @mixin grid-legacy-columns($breakpoint, $name) {
43 | // Do not make class if last media query
44 | @if is-same-breakpoint($breakpoint, $last) == false {
45 | // Loop each breakpoint to insert previous breakpoint classes inside this breakpoint’s media query
46 | // Ex: Make sure .yourPrefix-grid__col--sm--2 has correct sizes in the lg media query
47 | @each $currentName, $currentBreakpoint in $allBreakpoints {
48 | // Check if current breakpoint is not bigger than current media query
49 | @if map-get($breakpoint, breakpoint) >=
50 | map-get($currentBreakpoint, breakpoint)
51 | {
52 | // Loop each column in current breakpoint for new class
53 | // Ex: .yourPrefix-grid__col--sm--1, .yourPrefix-grid__col--sm--2, etc.
54 | @for $i from 1 through map-get($currentBreakpoint, columns) {
55 | $columnMultiplier: $i *
56 | map-get($breakpoint, columns) /
57 | map-get($currentBreakpoint, columns);
58 | $columnSize: get-fluid-size($name, $columnMultiplier);
59 |
60 | $isSecondToLast: is-same-breakpoint(
61 | $breakpoint,
62 | nth(nth($allBreakpoints, length($allBreakpoints) - 1), 2)
63 | );
64 |
65 | $maxColumnSize: get-fluid-size(
66 | nth(nth($allBreakpoints, length($allBreakpoints)), 1),
67 | $columnMultiplier
68 | );
69 |
70 | .#{$prefix}-grid__col--#{$currentName}--#{$i} {
71 | @if $includeFlexFallback {
72 | // If second-to-last media query, apply max-width instead of remaking classes in last media query
73 | @if $isSecondToLast {
74 | max-width: $maxColumnSize;
75 | }
76 | width: $columnSize;
77 | }
78 | grid-column: span #{$columnMultiplier};
79 |
80 | @if is-same-breakpoint($breakpoint, $last) == false {
81 | &.#{$prefix}-grid > *:not([class*="#{$prefix}-grid__col"]) {
82 | grid-column: span #{$i};
83 | }
84 | }
85 | }
86 |
87 | .#{$prefix}-grid--fluid-rows
88 | > .#{$prefix}-grid__height--#{$currentName}--#{$i} {
89 | grid-row: span $i;
90 | @if $includeFlexFallback {
91 | height: $columnSize;
92 | min-height: $columnSize;
93 | // If second-to-last media query, apply max-height instead of remaking classes in last media query
94 | @if $isSecondToLast {
95 | max-height: $maxColumnSize;
96 | }
97 | }
98 | }
99 | }
100 | }
101 | }
102 | }
103 |
104 | @if $includeFlexFallback {
105 | @if is-same-breakpoint($breakpoint, $last) {
106 | [class*="#{$prefix}-grid__col--"] {
107 | min-width: 0;
108 | }
109 | }
110 | }
111 | }
112 |
113 | // Set the height of an item for legacy grid
114 | @mixin grid-legacy-heights($name) {
115 | .#{$prefix}-grid__height--#{$name}--0 {
116 | height: 0;
117 | min-height: 0;
118 | }
119 | @for $i from 1 to $rows {
120 | .#{$prefix}-grid__height--#{$name}--#{$i} {
121 | grid-row: span $i;
122 | @if $includeFlexFallback {
123 | height: get-fixed-size($i);
124 | min-height: get-fixed-size($i);
125 | }
126 | }
127 | }
128 | }
129 |
130 | // If we need legacy grid, wrap this content in support tag
131 | @mixin grid-legacy-wrapper($includeFlexFallback) {
132 | @if $includeFlexFallback {
133 | @supports (display: grid) {
134 | @content;
135 | }
136 | } @else {
137 | @content;
138 | }
139 | }
140 |
141 | // Generate all classes for 0 and 0-only displaying, including custom breakpoints if they exist
142 | @mixin grid-legacy-zeros($breakpoint, $name) {
143 | // Undo previous breakpoint’s 0--only class
144 | @for $i from length($allBreakpoints) * -1 through -1 {
145 | $currentBreakpoint: nth($allBreakpoints, $i);
146 | @if map-get(nth($currentBreakpoint, 2), breakpoint) <
147 | map-get($breakpoint, breakpoint)
148 | {
149 | .#{$prefix}-grid__col--#{nth($currentBreakpoint, 1)}--0--only {
150 | display: block;
151 | }
152 | }
153 | }
154 |
155 | [class*="#{$prefix}-grid__col--#{$name}--"] {
156 | display: block;
157 | }
158 |
159 | .#{$prefix}-grid__col--#{$name}--0,
160 | .#{$prefix}-grid__col--#{$name}--0--only {
161 | display: none;
162 | }
163 | }
164 |
165 | // Set the width of a grid’s margin
166 | // and allow for a child to break out of the grid’s margin
167 | @mixin grid-margin($breakpoint, $name) {
168 | $nameToUse: $name;
169 | $margin: #{map-get($breakpoint, margin)};
170 | $padding: #{map-get($breakpoint, padding)};
171 |
172 | // If last breakpoint, we use the previous breakpoint name
173 | // to treat the last breakpoint as the max-width of the previous breakpoint
174 | @if is-same-breakpoint($breakpoint, $last) == true {
175 | $previousBreakpoint: nth(
176 | $allBreakpoints,
177 | index(map-keys($allBreakpoints), $name) - 1
178 | );
179 | $nameToUse: nth($previousBreakpoint, 1);
180 | }
181 |
182 | // Undo previous breakpoint’s bleeds and breaks
183 | @if is-same-breakpoint($breakpoint, $first) ==
184 | false and
185 | is-same-breakpoint($breakpoint, $last) ==
186 | false
187 | {
188 | $previousBreakpoint: nth(
189 | $allBreakpoints,
190 | index(map-keys($allBreakpoints), $name) - 1
191 | );
192 | $previousName: nth($previousBreakpoint, 1);
193 | $previousMargin: map-get(nth($previousBreakpoint, 2), margin);
194 |
195 | @if $previousMargin !=
196 | null and
197 | $previousMargin !=
198 | 0 and
199 | $previousMargin !=
200 | "0"
201 | {
202 | [class^="#{$prefix}-container__bleed--#{$previousName}"],
203 | [class^="#{$prefix}-container__break--#{$previousName}"] {
204 | margin-left: 0;
205 | margin-right: 0;
206 | padding-left: 0;
207 | padding-right: 0;
208 |
209 | &[class^="#{$prefix}-padding"] {
210 | padding-left: $padding;
211 | padding-right: $padding;
212 | }
213 | }
214 | }
215 | }
216 |
217 | @if $margin != null and $margin != 0 and $margin != "0" {
218 | $marginPlusPadding: calc(#{$margin} + #{$padding});
219 | @if $margin == "0" and $padding == "0" {
220 | $marginPlusPadding: 0;
221 | } @else if $margin == "0" {
222 | $marginPlusPadding: $padding;
223 | } @else if $padding == "0" {
224 | $marginPlusPadding: $margin;
225 | }
226 |
227 | .#{$prefix}-container {
228 | margin-left: auto;
229 | margin-right: auto;
230 | padding-left: $margin;
231 | padding-right: $margin;
232 | }
233 |
234 | .#{$prefix}-container--left {
235 | margin-left: 0;
236 | }
237 |
238 | .#{$prefix}-container--right {
239 | margin-right: 0;
240 | }
241 |
242 | .#{$prefix}-container__bleed--#{$nameToUse},
243 | .#{$prefix}-container__bleed--#{$nameToUse}--left,
244 | .#{$prefix}-container__break--#{$nameToUse},
245 | .#{$prefix}-container__break--#{$nameToUse}--left {
246 | margin-left: -#{$margin};
247 | }
248 |
249 | .#{$prefix}-container__bleed--#{$nameToUse},
250 | .#{$prefix}-container__bleed--#{$nameToUse}--right,
251 | .#{$prefix}-container__break--#{$nameToUse},
252 | .#{$prefix}-container__break--#{$nameToUse}--right {
253 | margin-right: -#{$margin};
254 | }
255 |
256 | .#{$prefix}-container__bleed--#{$nameToUse},
257 | .#{$prefix}-container__bleed--#{$nameToUse}--left {
258 | padding-left: $margin;
259 |
260 | &.#{$prefix}-padding,
261 | &.#{$prefix}-padding--horizontal,
262 | &.#{$prefix}-padding--left {
263 | padding-left: $marginPlusPadding;
264 | }
265 | }
266 |
267 | .#{$prefix}-container__bleed--#{$nameToUse},
268 | .#{$prefix}-container__bleed--#{$nameToUse}--right {
269 | padding-right: $margin;
270 |
271 | &.#{$prefix}-padding,
272 | &.#{$prefix}-padding--horizontal,
273 | &.#{$prefix}-padding--right {
274 | padding-right: $marginPlusPadding;
275 | }
276 | }
277 | }
278 | }
279 |
280 | // Classnames for different padding options
281 | @mixin grid-padding($breakpoint) {
282 | @if (map-get($breakpoint, padding) != null) {
283 | $padding: map-get($breakpoint, padding);
284 |
285 | .#{$prefix}-padding {
286 | padding: $padding;
287 | }
288 |
289 | .#{$prefix}-padding--bottom {
290 | padding-bottom: $padding;
291 | }
292 |
293 | .#{$prefix}-padding--left {
294 | padding-left: $padding;
295 | }
296 |
297 | .#{$prefix}-padding--right {
298 | padding-right: $padding;
299 | }
300 |
301 | .#{$prefix}-padding--top {
302 | padding-top: $padding;
303 | }
304 |
305 | .#{$prefix}-padding--horizontal {
306 | padding-left: $padding;
307 | padding-right: $padding;
308 | }
309 |
310 | .#{$prefix}-padding--vertical {
311 | padding-bottom: $padding;
312 | padding-top: $padding;
313 | }
314 | }
315 | }
316 |
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/scss/_sass-list-maps.scss:
--------------------------------------------------------------------------------
1 | /// _
2 | /// | |
3 | /// ___ __ _ ___ ___ ______ _ __ ___ __ _ _ __ ___ ______ _ __ | |_ _ ___
4 | /// / __|/ _` / __/ __|______| '_ ` _ \ / _` | '_ \/ __|______| '_ \| | | | / __|
5 | /// \__ \ (_| \__ \__ \ | | | | | | (_| | |_) \__ \ | |_) | | |_| \__ \
6 | /// |___/\__,_|___/___/ |_| |_| |_|\__,_| .__/|___/ | .__/|_|\__,_|___/
7 | /// | | | |
8 | /// |_| |_|
9 | /// Sass Maps Plus 0.9.2
10 | /// Advanced map and list-map manipulation for all versions of Sass
11 | /// MIT License
12 | /// @author Lu Nelson
13 |
14 | /// Global sort direction: either `asc` or `desc`
15 | /// @access public
16 | /// @group map-lists/map-maps
17 | $maps-sort-dir: "asc";
18 |
19 | /// get value at nested or 'deep' key, per $keys list
20 | /// @access public
21 | /// @group maps
22 | /// @param {Map} $map - map
23 | /// @param {Arglist} $keys - nested keys
24 | /// @return {*}
25 | @function map-get-nested($map, $keys...) {
26 | @if length($map) == 0 {
27 | @return null;
28 | }
29 | @each $key in $keys {
30 | @if type-of($map) != "map" {
31 | @return $map;
32 | }
33 | $map: map-get($map, $key);
34 | }
35 | @return $map;
36 | }
37 |
38 | /// Sort a list-of-maps or map-of-maps, based on value at key(s) in maps
39 | /// @access public
40 | /// @group map-lists/map-maps
41 | /// @param {Map|List} $maps - Map of maps, or List of maps, to sort
42 | /// @param {Arglist} $keys - Chain of keys to the value that will be sorted for
43 | /// @return {Map|List}
44 | /// @require {function} map-get-nested
45 | @function maps-sort($maps, $keys...) {
46 | @if length($keys) == 0 {
47 | @return $maps;
48 | }
49 |
50 | @if length($maps) > 1 {
51 | $less: ();
52 | $equal: ();
53 | $greater: ();
54 |
55 | $map-of-maps: type-of($maps) == "map";
56 |
57 | @if $map-of-maps {
58 | $seed-map: nth(nth($maps, ceil(length($maps) / 2)), 2);
59 |
60 | $seed-value: map-get-nested($seed-map, $keys...);
61 |
62 | // TODO: add code to handle case of non-number values (warn and return $maps)
63 |
64 | @each $key, $map in $maps {
65 | $curr-value: map-get-nested($map, $keys...);
66 |
67 | @if $curr-value == $seed-value {
68 | $equal: map-merge($equal, ($key: $map));
69 | } @else if $curr-value < $seed-value {
70 | @if $maps-sort-dir == "asc" {
71 | $less: map-merge($less, ($key: $map));
72 | } @else {
73 | $greater: map-merge($greater, ($key: $map));
74 | }
75 | } @else {
76 | @if $maps-sort-dir == "asc" {
77 | $greater: map-merge($greater, ($key: $map));
78 | } @else {
79 | $less: map-merge($less, ($key: $map));
80 | }
81 | }
82 | }
83 |
84 | $less: maps-sort($less, $keys...);
85 | $greater: maps-sort($greater, $keys...);
86 |
87 | @return map-merge(map-merge($less, $equal), $greater);
88 | } @else {
89 | $seed-map: nth($maps, ceil(length($maps) / 2));
90 |
91 | $seed-value: map-get-nested($seed-map, $keys...);
92 |
93 | @each $map in $maps {
94 | $curr-value: map-get-nested($map, $keys...);
95 |
96 | @if $curr-value == $seed-value {
97 | $equal: append($equal, $map);
98 | } @else if $curr-value < $seed-value {
99 | @if $maps-sort-dir == "asc" {
100 | $less: append($less, $map);
101 | } @else {
102 | $greater: append($greater, $map);
103 | }
104 | } @else {
105 | @if $maps-sort-dir == "asc" {
106 | $greater: append($greater, $map);
107 | } @else {
108 | $less: append($less, $map);
109 | }
110 | }
111 | }
112 |
113 | $less: maps-sort($less, $keys...);
114 | $greater: maps-sort($greater, $keys...);
115 |
116 | @return join(join($less, $equal), $greater);
117 | }
118 | }
119 |
120 | @return $maps;
121 | }
122 |
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/scss/_utilities.scss:
--------------------------------------------------------------------------------
1 | @import "functions";
2 | @import "values";
3 | @import "variables";
4 |
5 | /// Function returns the value for a given breakpoint.
6 | /// @param {String} $breakpointName Breakpoint name.
7 | /// @return {Length} The breakpoint value in rems.
8 | @function get-breakpoint-value($breakpointName) {
9 | $breakpointValue: map-deep-get(
10 | $breakpointsAndArtboards,
11 | $breakpointName,
12 | "breakpoint"
13 | );
14 |
15 | @return $breakpointValue * 1rem;
16 | }
17 |
18 | /// Returns a calc() expression that represents a fluid width at a given breakpoint.
19 | /// @param {String} $breakpointName A valid breakpoint.
20 | /// @param {Number} $columnSpan The number of columns to span across.
21 | /// @return {Length} A calc() expression representing fluid width.
22 | /// @example scss
23 | /// button {
24 | /// @include media-query('sm') {
25 | /// max-width: get-fluid-size('sm', 1);
26 | /// }
27 | /// }
28 | /// @output css
29 | /// @media screen and (min-width: 20rem) {
30 | /// button {
31 | /// max-width: 25vw;
32 | /// }
33 | /// }
34 | @function get-fluid-size($breakpointName, $columnSpan) {
35 | $breakpoint: map-get($breakpointsAndArtboards, $breakpointName);
36 |
37 | @if ($breakpoint == null or type-of($breakpoint) != "map") {
38 | @error "The provided breakpoint `#{$breakpointName}` is not a valid breakpoint found in breakpoints or extraArtboards in $grid-values. Please double-check your grid configuration.";
39 | }
40 |
41 | $columnTotal: map-get($breakpoint, columns);
42 | $margin: map-get($breakpoint, margin);
43 |
44 | @if ($columnTotal == null or type-of($columnTotal) != "number") {
45 | @error "The provided breakpoint `#{$breakpointName}` needs to have a total number of columns set in $grid-values. Please double-check your grid configuration.";
46 | }
47 |
48 | @if ($columnSpan == null or type-of($columnSpan) != "number") {
49 | @error "The number of columns to span for the breakpoint `#{$breakpointName}` must be a valid number. The provided column span value `#{$columnSpan}` is not a number";
50 | }
51 |
52 | @if ($columnSpan > $columnTotal or $columnSpan <= 0) {
53 | @error "The number of columns to span for the breakpoint `#{$breakpointName}` must be greater than 0 and less than or equal to the total number of columns for this breakpoint. The provided column value `#{$columnSpan}` does not meet this criteria";
54 | }
55 |
56 | $container: 100vw;
57 | // Last breakpoint is a max-width and should be a fixed number
58 | @if is-same-breakpoint($breakpoint, $last) {
59 | $container: map-get($breakpoint, breakpoint) * 1rem;
60 | }
61 |
62 | $multiplier: round-decimal($columnSpan / $columnTotal, 4, floor);
63 |
64 | // For IE, we can't have a 0 in the $fluidWidth calc().
65 | @if ($margin == 0) {
66 | @return $container * $multiplier;
67 | }
68 |
69 | @return calc((#{$container} - #{$margin * 2}) * #{$multiplier});
70 | }
71 |
72 | /// Function gets a calculated rem value for a fixed size.
73 | /// @param {Number} $unitQuantity Fixed nondimensional units.
74 | /// @return {Length} A calculated rem value.
75 | /// @example scss
76 | /// button {
77 | /// @include media-query('sm') {
78 | /// max-width: get-fixed-size(10);
79 | /// }
80 | /// }
81 | /// @output css
82 | /// @media screen and (min-width: 20rem) {
83 | /// button {
84 | /// max-width: 5rem;
85 | /// }
86 | /// }
87 | @function get-fixed-size($unitQuantity) {
88 | // Derive the base unit from the current row height of the grid
89 | $fixedUnit: map-get($grid-values, "rowHeight");
90 |
91 | @if ($fixedUnit == null or type-of($fixedUnit) != "number") {
92 | @error "The rowHeight in $grid-values needs be a valid number. Please check your grid configuration.";
93 | }
94 |
95 | @if ($unitQuantity == null or type-of($unitQuantity) != "number") {
96 | @error "The provided fixed value `#{$unitQuantity}` to get-fixed-size() needs to be a valid number greater than 0.";
97 | }
98 |
99 | @return $unitQuantity * $fixedUnit * 1rem;
100 | }
101 |
102 | /// Utility for declaring mobile-first media queries.
103 | /// @param {String} $breakpointName The name of the breakpoint to set its width value to media query.
104 | @mixin media-query($breakpointName) {
105 | $breakpointValue: get-breakpoint-value($breakpointName);
106 | @if $breakpointValue == map-get($first, breakpoint) {
107 | @content;
108 | } @else {
109 | @media screen and (min-width: #{$breakpointValue}) {
110 | @content;
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/scss/_values.scss:
--------------------------------------------------------------------------------
1 | $grid-values: (
2 | prefix: bx,
3 | breakpoints: (
4 | sm: (
5 | breakpoint: 20,
6 | columns: 12,
7 | gutter: 1.250rem,
8 | margin: 5vw
9 | ),
10 | xxl: (
11 | breakpoint: 100,
12 | columns: 12,
13 | gutter: 1.250rem,
14 | margin: 5vw
15 | )
16 | ),
17 | extraArtboards: (
18 | md: 48,
19 | lg: 62,
20 | xl: 75
21 | ),
22 | rem: 16,
23 | rowHeight: 0.5,
24 | rows: 30,
25 | paths: null
26 | );
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/scss/_variables.scss:
--------------------------------------------------------------------------------
1 | @import "values";
2 |
3 | $prefix: gridish !default;
4 | @if map-get($grid-values, "prefix") and $prefix == "gridish" {
5 | $prefix: map-get($grid-values, "prefix");
6 | }
7 | $extraBreakpoints: () !default;
8 | $breakpoints: add-padding(map-get($grid-values, "breakpoints"));
9 | $first: nth(nth($breakpoints, 1), 2);
10 | $last: nth(nth($breakpoints, -1), 2);
11 | $includeFlexFallback: false !default;
12 | $rowHeight: map-get($grid-values, "rowHeight");
13 | $rows: map-get($grid-values, "rows");
14 | $extraArtboards: map-get($grid-values, "extraArtboards");
15 | $allBreakpoints: all-breakpoints(
16 | $breakpoints,
17 | $extraBreakpoints,
18 | $first,
19 | $last
20 | );
21 | $breakpointsAndArtboards: all-breakpoints(
22 | $breakpoints,
23 | $extraArtboards,
24 | $first,
25 | $last
26 | );
27 |
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/scss/bx-grid-legacy.scss:
--------------------------------------------------------------------------------
1 | $includeFlexFallback: true;
2 | @import "core.scss";
3 |
4 | @supports (display: grid) {
5 | .#{$prefix}-grid > *,
6 | .#{$prefix}-grid > [class*="#{$prefix}-grid__col--"] {
7 | min-width: initial;
8 | max-width: initial;
9 | width: initial;
10 |
11 | &.#{$prefix}-grid {
12 | display: grid;
13 | }
14 | }
15 |
16 | .#{$prefix}-grid > [class*="#{$prefix}-grid__height--"] {
17 | height: unset;
18 | max-height: unset;
19 | min-height: initial;
20 | }
21 | }
22 |
23 | .#{$prefix}-grid > script {
24 | display: none;
25 | }
26 |
--------------------------------------------------------------------------------
/examples/carbon/css-gridish/scss/bx-grid.scss:
--------------------------------------------------------------------------------
1 | @import "core.scss";
2 |
--------------------------------------------------------------------------------
/examples/carbon/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
42 |
43 |
44 |
45 |
46 |
CSS Gridish
47 |
Carbon Example
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
Learn more about
56 | CSS Gridish.
57 |
58 |
Also check out our examples of CSS Gridish making grid code for
59 | Bootstrap and
60 | Material.
61 |
62 |
63 |
64 |
89 |
90 |
--------------------------------------------------------------------------------
/examples/carbon/intro.md:
--------------------------------------------------------------------------------
1 | # Carbon Design Grid
2 |
3 | An example of [CSS Gridish](../../../README.md) generating CSS Grid code, fallback flexbox code, dev documentation, and Sketch files based on the [Carbon Design System grid.](https://github.com/carbon-design-system/carbon-components/blob/master/src/globals/grid/_grid.scss#L29-L31)
4 |
--------------------------------------------------------------------------------
/examples/carbon/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css-gridish-example-carbon",
3 | "version": "0.0.1",
4 | "engines": {
5 | "node": ">=8.2.0"
6 | },
7 | "repository": {
8 | "type": "git",
9 | "url": "git@ibm.com:ibm/css-gridish.git"
10 | },
11 | "author": "James Y. Rauhut ",
12 | "license": "Apache-2.0",
13 | "scripts": {
14 | "build": "node ../../bin/index.js",
15 | "test": "true"
16 | },
17 | "dependencies": {}
18 | }
19 |
--------------------------------------------------------------------------------
/examples/carbon/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examples/material/README.md:
--------------------------------------------------------------------------------
1 | # CSS Gridish: Material Design Example
2 |
3 | [View a random layout with this grid.](https://ibm.github.io/css-gridish/examples/material/index.html)
4 |
5 | [View a UI layout with this grid, including a CSS Flexbox fallback.](https://ibm.github.io/css-gridish/examples/material/example.html)
6 |
7 | An example of [CSS Gridish](../../README.md) generating CSS Grid code, fallback flexbox code, dev documentation, and Sketch files based on [Material Design’s grid.](https://material.io/guidelines/layout/responsive-ui.html#responsive-ui-grid)
8 |
9 | Check out everything CSS Gridish made based off of the [config file](./css-gridish.json) in the [css-gridish folder.](./css-gridish/)
10 |
--------------------------------------------------------------------------------
/examples/material/css-gridish.json:
--------------------------------------------------------------------------------
1 | {
2 | "prefix": "material",
3 | "breakpoints": {
4 | "xsmall": {
5 | "breakpoint": 22.5,
6 | "columns": 4,
7 | "gutter": "1rem",
8 | "margin": 0
9 | },
10 | "small": {
11 | "breakpoint": 37.5,
12 | "columns": 8,
13 | "gutter": "1rem",
14 | "margin": 0
15 | },
16 | "medium": {
17 | "breakpoint": 64,
18 | "columns": 12,
19 | "gutter": "2rem",
20 | "margin": 0
21 | },
22 | "xlarge": {
23 | "breakpoint": 120,
24 | "columns": 12,
25 | "gutter": "2rem",
26 | "margin": 0
27 | }
28 | },
29 | "extraArtboards": {
30 | "large": 90
31 | },
32 | "rem": 16,
33 | "rowHeight": 0.5,
34 | "rows": 30,
35 | "paths": {
36 | "intro": "intro.md"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/examples/material/css-gridish/material-grid.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/examples/material/css-gridish/material-grid.sketch
--------------------------------------------------------------------------------
/examples/material/css-gridish/scss/_core.scss:
--------------------------------------------------------------------------------
1 | @import "functions.scss";
2 | @import "mixins.scss";
3 | @import "variables.scss";
4 | @import "utilities.scss";
5 |
6 | html {
7 | font-size: map-get($grid-values, "rem") * 1px;
8 | }
9 |
10 | body {
11 | margin: 0;
12 | }
13 |
14 | .#{$prefix}-container {
15 | box-sizing: border-box;
16 | margin-left: auto;
17 | margin-right: auto;
18 | max-width: #{map-get($last, breakpoint)}rem;
19 | overflow-x: hidden;
20 | width: 100vw;
21 | }
22 |
23 | .#{$prefix}-container--left {
24 | margin-left: 0;
25 | }
26 |
27 | .#{$prefix}-container--right {
28 | margin-right: 0;
29 | }
30 |
31 | .#{$prefix}-grid {
32 | align-items: flex-start;
33 | box-sizing: border-box;
34 | @if $includeFlexFallback {
35 | display: flex;
36 | }
37 | display: grid;
38 | flex-wrap: wrap;
39 | position: relative;
40 |
41 | > * {
42 | box-sizing: border-box;
43 |
44 | :last-child,
45 | :last-child > :last-child,
46 | :last-child > :last-child > :last-child {
47 | margin-bottom: 0;
48 | }
49 | }
50 | }
51 |
52 | [class*="#{$prefix}-padding"] {
53 | box-sizing: border-box;
54 | }
55 |
56 | // Rules needed in legacy, but needed to change in CSS Grid
57 | @if $includeFlexFallback {
58 | .#{$prefix}-grid > * {
59 | width: 100%;
60 | }
61 |
62 | @supports (display: grid) {
63 | .#{$prefix}-grid {
64 | align-items: unset;
65 | }
66 |
67 | .#{$prefix}-grid > * {
68 | width: initial;
69 | }
70 | }
71 | }
72 |
73 | // Rules not needed in legacy, but needed in CSS Grid
74 | @supports (display: grid) {
75 | .#{$prefix}-grid > * {
76 | height: 100%;
77 | }
78 | }
79 |
80 | @include grid-legacy-wrapper($includeFlexFallback) {
81 | :root {
82 | @include grid-heights-fixed($rows);
83 | }
84 | }
85 |
86 | @each $name, $breakpoint in $allBreakpoints {
87 | @include media-query($name) {
88 | @if is-same-breakpoint($breakpoint, $last) == false {
89 | @include grid-legacy-heights($name);
90 | }
91 | @include grid-legacy-zeros($breakpoint, $name);
92 | @include grid-padding($breakpoint);
93 | @include grid($breakpoint, $name);
94 | @include grid-legacy-columns($breakpoint, $name);
95 |
96 | // Wrap all bleed/break classes and css variables in a CSS Grid support query
97 | @include grid-legacy-wrapper($includeFlexFallback) {
98 | @include grid-margin($breakpoint, $name);
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/examples/material/css-gridish/scss/_functions.scss:
--------------------------------------------------------------------------------
1 | @import "sass-list-maps";
2 |
3 | // Transform the gutter property into a padding property for web
4 | @function add-padding($breakpoints) {
5 | $cleanBreakpoints: ();
6 | @each $name, $breakpoint in $breakpoints {
7 | $cleanBreakpoints: map-merge(
8 | $cleanBreakpoints,
9 | (
10 | $name:
11 | map-merge($breakpoint, (padding: map-get($breakpoint, gutter) / 2))
12 | )
13 | );
14 | }
15 |
16 | @return $cleanBreakpoints;
17 | }
18 |
19 | // Merge standard and custom breakpoints into list
20 | @function all-breakpoints($breakpoints, $extraBreakpoints, $first, $last) {
21 | $allBreakpoints: $breakpoints;
22 | @each $currentBreakpoint in $extraBreakpoints {
23 | $extraBreakpointName: nth($currentBreakpoint, 1);
24 | $extraBreakpointWidth: nth($currentBreakpoint, 2);
25 | $found: false;
26 | $match: null;
27 | @each $majorBreakpoint in $breakpoints {
28 | @if $found == false {
29 | @if map-get(nth($majorBreakpoint, 2), breakpoint) >
30 | $extraBreakpointWidth
31 | {
32 | $found: true;
33 | } @else {
34 | $match: $majorBreakpoint;
35 | }
36 | }
37 | }
38 | @if $extraBreakpointWidth > map-get($last, breakpoint) {
39 | $match: (
40 | last,
41 | $last
42 | );
43 | }
44 | @if $extraBreakpointWidth < map-get($first, breakpoint) {
45 | $match: (
46 | first,
47 | $first
48 | );
49 | }
50 |
51 | $newBreakpoint: map-merge(
52 | nth($match, 2),
53 | (breakpoint: $extraBreakpointWidth)
54 | );
55 | $currentBreakpoint: (
56 | $extraBreakpointName:
57 | map-merge(nth($match, 2), (breakpoint: $extraBreakpointWidth))
58 | );
59 | $allBreakpoints: map-merge($allBreakpoints, $currentBreakpoint);
60 | }
61 |
62 | @return maps-sort($allBreakpoints, breakpoint);
63 | }
64 |
65 | @function is-same-breakpoint($a, $b) {
66 | @return map-get($a, breakpoint) == map-get($b, breakpoint);
67 | }
68 |
69 | /// Traverse maps and retrieve deeply nested values: https://css-tricks.com/snippets/sass/deep-getset-maps/
70 | /// @author Hugo Giraudel
71 | /// @param {Map} $map A sass map and any number of keys.
72 | /// @param {*} $keys Nested values.
73 | /// @return Nested values or nested map.
74 | @function map-deep-get($map, $keys...) {
75 | @each $key in $keys {
76 | $map: map-get($map, $key);
77 | }
78 | @return $map;
79 | }
80 |
81 | // _decimal.scss | MIT License | gist.github.com/terkel/4373420
82 | @function round-decimal($number, $digits: 0, $mode: round) {
83 | $n: 1;
84 | // $number must be a number
85 | @if type-of($number) != number {
86 | @warn "#{ $number } is not a number.";
87 | @return $number;
88 | }
89 | // $digits must be a unitless number
90 | @if type-of($digits) != number {
91 | @warn "#{ $digits } is not a number.";
92 | @return $number;
93 | } @else if not unitless($digits) {
94 | @warn "#{ $digits } has a unit.";
95 | @return $number;
96 | }
97 | @for $i from 1 through $digits {
98 | $n: $n * 10;
99 | }
100 | @if $mode == round {
101 | @return round($number * $n) / $n;
102 | } @else if $mode == ceil {
103 | @return ceil($number * $n) / $n;
104 | } @else if $mode == floor {
105 | @return floor($number * $n) / $n;
106 | } @else {
107 | @warn "#{ $mode } is undefined keyword.";
108 | @return $number;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/examples/material/css-gridish/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Set the width of a grid’s column
2 | @mixin grid($breakpoint, $breakpointName) {
3 | @if (map-get($breakpoint, columns) != null) {
4 | $columnSize: get-fluid-size($breakpointName, 1);
5 |
6 | .#{$prefix}-grid {
7 | @if is-same-breakpoint($breakpoint, $first) {
8 | grid-auto-rows: minmax($rowHeight * 1rem, min-content);
9 | }
10 | grid-template-columns: repeat(auto-fill, $columnSize);
11 |
12 | &.#{$prefix}-grid--fixed-columns {
13 | grid-template-columns: repeat(
14 | auto-fill,
15 | map-get($breakpoint, breakpoint) *
16 | 1rem /
17 | map-get($breakpoint, columns)
18 | );
19 | }
20 |
21 | &.#{$prefix}-grid--fluid-rows {
22 | grid-auto-rows: $columnSize;
23 | }
24 |
25 | @if is-same-breakpoint($breakpoint, $last) == false {
26 | > * {
27 | grid-column: span #{map-get($breakpoint, columns)};
28 | }
29 | }
30 | }
31 | }
32 | }
33 |
34 | // Generate variables for commonly used rows
35 | @mixin grid-heights-fixed($rows) {
36 | @for $i from 1 to $rows {
37 | --#{$prefix}-height-#{$i}: get-fixed-size($i);
38 | }
39 | }
40 |
41 | // Set the width of a grid’s column for legacy grid
42 | @mixin grid-legacy-columns($breakpoint, $name) {
43 | // Do not make class if last media query
44 | @if is-same-breakpoint($breakpoint, $last) == false {
45 | // Loop each breakpoint to insert previous breakpoint classes inside this breakpoint’s media query
46 | // Ex: Make sure .yourPrefix-grid__col--sm--2 has correct sizes in the lg media query
47 | @each $currentName, $currentBreakpoint in $allBreakpoints {
48 | // Check if current breakpoint is not bigger than current media query
49 | @if map-get($breakpoint, breakpoint) >=
50 | map-get($currentBreakpoint, breakpoint)
51 | {
52 | // Loop each column in current breakpoint for new class
53 | // Ex: .yourPrefix-grid__col--sm--1, .yourPrefix-grid__col--sm--2, etc.
54 | @for $i from 1 through map-get($currentBreakpoint, columns) {
55 | $columnMultiplier: $i *
56 | map-get($breakpoint, columns) /
57 | map-get($currentBreakpoint, columns);
58 | $columnSize: get-fluid-size($name, $columnMultiplier);
59 |
60 | $isSecondToLast: is-same-breakpoint(
61 | $breakpoint,
62 | nth(nth($allBreakpoints, length($allBreakpoints) - 1), 2)
63 | );
64 |
65 | $maxColumnSize: get-fluid-size(
66 | nth(nth($allBreakpoints, length($allBreakpoints)), 1),
67 | $columnMultiplier
68 | );
69 |
70 | .#{$prefix}-grid__col--#{$currentName}--#{$i} {
71 | @if $includeFlexFallback {
72 | // If second-to-last media query, apply max-width instead of remaking classes in last media query
73 | @if $isSecondToLast {
74 | max-width: $maxColumnSize;
75 | }
76 | width: $columnSize;
77 | }
78 | grid-column: span #{$columnMultiplier};
79 |
80 | @if is-same-breakpoint($breakpoint, $last) == false {
81 | &.#{$prefix}-grid > *:not([class*="#{$prefix}-grid__col"]) {
82 | grid-column: span #{$i};
83 | }
84 | }
85 | }
86 |
87 | .#{$prefix}-grid--fluid-rows
88 | > .#{$prefix}-grid__height--#{$currentName}--#{$i} {
89 | grid-row: span $i;
90 | @if $includeFlexFallback {
91 | height: $columnSize;
92 | min-height: $columnSize;
93 | // If second-to-last media query, apply max-height instead of remaking classes in last media query
94 | @if $isSecondToLast {
95 | max-height: $maxColumnSize;
96 | }
97 | }
98 | }
99 | }
100 | }
101 | }
102 | }
103 |
104 | @if $includeFlexFallback {
105 | @if is-same-breakpoint($breakpoint, $last) {
106 | [class*="#{$prefix}-grid__col--"] {
107 | min-width: 0;
108 | }
109 | }
110 | }
111 | }
112 |
113 | // Set the height of an item for legacy grid
114 | @mixin grid-legacy-heights($name) {
115 | .#{$prefix}-grid__height--#{$name}--0 {
116 | height: 0;
117 | min-height: 0;
118 | }
119 | @for $i from 1 to $rows {
120 | .#{$prefix}-grid__height--#{$name}--#{$i} {
121 | grid-row: span $i;
122 | @if $includeFlexFallback {
123 | height: get-fixed-size($i);
124 | min-height: get-fixed-size($i);
125 | }
126 | }
127 | }
128 | }
129 |
130 | // If we need legacy grid, wrap this content in support tag
131 | @mixin grid-legacy-wrapper($includeFlexFallback) {
132 | @if $includeFlexFallback {
133 | @supports (display: grid) {
134 | @content;
135 | }
136 | } @else {
137 | @content;
138 | }
139 | }
140 |
141 | // Generate all classes for 0 and 0-only displaying, including custom breakpoints if they exist
142 | @mixin grid-legacy-zeros($breakpoint, $name) {
143 | // Undo previous breakpoint’s 0--only class
144 | @for $i from length($allBreakpoints) * -1 through -1 {
145 | $currentBreakpoint: nth($allBreakpoints, $i);
146 | @if map-get(nth($currentBreakpoint, 2), breakpoint) <
147 | map-get($breakpoint, breakpoint)
148 | {
149 | .#{$prefix}-grid__col--#{nth($currentBreakpoint, 1)}--0--only {
150 | display: block;
151 | }
152 | }
153 | }
154 |
155 | [class*="#{$prefix}-grid__col--#{$name}--"] {
156 | display: block;
157 | }
158 |
159 | .#{$prefix}-grid__col--#{$name}--0,
160 | .#{$prefix}-grid__col--#{$name}--0--only {
161 | display: none;
162 | }
163 | }
164 |
165 | // Set the width of a grid’s margin
166 | // and allow for a child to break out of the grid’s margin
167 | @mixin grid-margin($breakpoint, $name) {
168 | $nameToUse: $name;
169 | $margin: #{map-get($breakpoint, margin)};
170 | $padding: #{map-get($breakpoint, padding)};
171 |
172 | // If last breakpoint, we use the previous breakpoint name
173 | // to treat the last breakpoint as the max-width of the previous breakpoint
174 | @if is-same-breakpoint($breakpoint, $last) == true {
175 | $previousBreakpoint: nth(
176 | $allBreakpoints,
177 | index(map-keys($allBreakpoints), $name) - 1
178 | );
179 | $nameToUse: nth($previousBreakpoint, 1);
180 | }
181 |
182 | // Undo previous breakpoint’s bleeds and breaks
183 | @if is-same-breakpoint($breakpoint, $first) ==
184 | false and
185 | is-same-breakpoint($breakpoint, $last) ==
186 | false
187 | {
188 | $previousBreakpoint: nth(
189 | $allBreakpoints,
190 | index(map-keys($allBreakpoints), $name) - 1
191 | );
192 | $previousName: nth($previousBreakpoint, 1);
193 | $previousMargin: map-get(nth($previousBreakpoint, 2), margin);
194 |
195 | @if $previousMargin !=
196 | null and
197 | $previousMargin !=
198 | 0 and
199 | $previousMargin !=
200 | "0"
201 | {
202 | [class^="#{$prefix}-container__bleed--#{$previousName}"],
203 | [class^="#{$prefix}-container__break--#{$previousName}"] {
204 | margin-left: 0;
205 | margin-right: 0;
206 | padding-left: 0;
207 | padding-right: 0;
208 |
209 | &[class^="#{$prefix}-padding"] {
210 | padding-left: $padding;
211 | padding-right: $padding;
212 | }
213 | }
214 | }
215 | }
216 |
217 | @if $margin != null and $margin != 0 and $margin != "0" {
218 | $marginPlusPadding: calc(#{$margin} + #{$padding});
219 | @if $margin == "0" and $padding == "0" {
220 | $marginPlusPadding: 0;
221 | } @else if $margin == "0" {
222 | $marginPlusPadding: $padding;
223 | } @else if $padding == "0" {
224 | $marginPlusPadding: $margin;
225 | }
226 |
227 | .#{$prefix}-container {
228 | margin-left: auto;
229 | margin-right: auto;
230 | padding-left: $margin;
231 | padding-right: $margin;
232 | }
233 |
234 | .#{$prefix}-container--left {
235 | margin-left: 0;
236 | }
237 |
238 | .#{$prefix}-container--right {
239 | margin-right: 0;
240 | }
241 |
242 | .#{$prefix}-container__bleed--#{$nameToUse},
243 | .#{$prefix}-container__bleed--#{$nameToUse}--left,
244 | .#{$prefix}-container__break--#{$nameToUse},
245 | .#{$prefix}-container__break--#{$nameToUse}--left {
246 | margin-left: -#{$margin};
247 | }
248 |
249 | .#{$prefix}-container__bleed--#{$nameToUse},
250 | .#{$prefix}-container__bleed--#{$nameToUse}--right,
251 | .#{$prefix}-container__break--#{$nameToUse},
252 | .#{$prefix}-container__break--#{$nameToUse}--right {
253 | margin-right: -#{$margin};
254 | }
255 |
256 | .#{$prefix}-container__bleed--#{$nameToUse},
257 | .#{$prefix}-container__bleed--#{$nameToUse}--left {
258 | padding-left: $margin;
259 |
260 | &.#{$prefix}-padding,
261 | &.#{$prefix}-padding--horizontal,
262 | &.#{$prefix}-padding--left {
263 | padding-left: $marginPlusPadding;
264 | }
265 | }
266 |
267 | .#{$prefix}-container__bleed--#{$nameToUse},
268 | .#{$prefix}-container__bleed--#{$nameToUse}--right {
269 | padding-right: $margin;
270 |
271 | &.#{$prefix}-padding,
272 | &.#{$prefix}-padding--horizontal,
273 | &.#{$prefix}-padding--right {
274 | padding-right: $marginPlusPadding;
275 | }
276 | }
277 | }
278 | }
279 |
280 | // Classnames for different padding options
281 | @mixin grid-padding($breakpoint) {
282 | @if (map-get($breakpoint, padding) != null) {
283 | $padding: map-get($breakpoint, padding);
284 |
285 | .#{$prefix}-padding {
286 | padding: $padding;
287 | }
288 |
289 | .#{$prefix}-padding--bottom {
290 | padding-bottom: $padding;
291 | }
292 |
293 | .#{$prefix}-padding--left {
294 | padding-left: $padding;
295 | }
296 |
297 | .#{$prefix}-padding--right {
298 | padding-right: $padding;
299 | }
300 |
301 | .#{$prefix}-padding--top {
302 | padding-top: $padding;
303 | }
304 |
305 | .#{$prefix}-padding--horizontal {
306 | padding-left: $padding;
307 | padding-right: $padding;
308 | }
309 |
310 | .#{$prefix}-padding--vertical {
311 | padding-bottom: $padding;
312 | padding-top: $padding;
313 | }
314 | }
315 | }
316 |
--------------------------------------------------------------------------------
/examples/material/css-gridish/scss/_sass-list-maps.scss:
--------------------------------------------------------------------------------
1 | /// _
2 | /// | |
3 | /// ___ __ _ ___ ___ ______ _ __ ___ __ _ _ __ ___ ______ _ __ | |_ _ ___
4 | /// / __|/ _` / __/ __|______| '_ ` _ \ / _` | '_ \/ __|______| '_ \| | | | / __|
5 | /// \__ \ (_| \__ \__ \ | | | | | | (_| | |_) \__ \ | |_) | | |_| \__ \
6 | /// |___/\__,_|___/___/ |_| |_| |_|\__,_| .__/|___/ | .__/|_|\__,_|___/
7 | /// | | | |
8 | /// |_| |_|
9 | /// Sass Maps Plus 0.9.2
10 | /// Advanced map and list-map manipulation for all versions of Sass
11 | /// MIT License
12 | /// @author Lu Nelson
13 |
14 | /// Global sort direction: either `asc` or `desc`
15 | /// @access public
16 | /// @group map-lists/map-maps
17 | $maps-sort-dir: "asc";
18 |
19 | /// get value at nested or 'deep' key, per $keys list
20 | /// @access public
21 | /// @group maps
22 | /// @param {Map} $map - map
23 | /// @param {Arglist} $keys - nested keys
24 | /// @return {*}
25 | @function map-get-nested($map, $keys...) {
26 | @if length($map) == 0 {
27 | @return null;
28 | }
29 | @each $key in $keys {
30 | @if type-of($map) != "map" {
31 | @return $map;
32 | }
33 | $map: map-get($map, $key);
34 | }
35 | @return $map;
36 | }
37 |
38 | /// Sort a list-of-maps or map-of-maps, based on value at key(s) in maps
39 | /// @access public
40 | /// @group map-lists/map-maps
41 | /// @param {Map|List} $maps - Map of maps, or List of maps, to sort
42 | /// @param {Arglist} $keys - Chain of keys to the value that will be sorted for
43 | /// @return {Map|List}
44 | /// @require {function} map-get-nested
45 | @function maps-sort($maps, $keys...) {
46 | @if length($keys) == 0 {
47 | @return $maps;
48 | }
49 |
50 | @if length($maps) > 1 {
51 | $less: ();
52 | $equal: ();
53 | $greater: ();
54 |
55 | $map-of-maps: type-of($maps) == "map";
56 |
57 | @if $map-of-maps {
58 | $seed-map: nth(nth($maps, ceil(length($maps) / 2)), 2);
59 |
60 | $seed-value: map-get-nested($seed-map, $keys...);
61 |
62 | // TODO: add code to handle case of non-number values (warn and return $maps)
63 |
64 | @each $key, $map in $maps {
65 | $curr-value: map-get-nested($map, $keys...);
66 |
67 | @if $curr-value == $seed-value {
68 | $equal: map-merge($equal, ($key: $map));
69 | } @else if $curr-value < $seed-value {
70 | @if $maps-sort-dir == "asc" {
71 | $less: map-merge($less, ($key: $map));
72 | } @else {
73 | $greater: map-merge($greater, ($key: $map));
74 | }
75 | } @else {
76 | @if $maps-sort-dir == "asc" {
77 | $greater: map-merge($greater, ($key: $map));
78 | } @else {
79 | $less: map-merge($less, ($key: $map));
80 | }
81 | }
82 | }
83 |
84 | $less: maps-sort($less, $keys...);
85 | $greater: maps-sort($greater, $keys...);
86 |
87 | @return map-merge(map-merge($less, $equal), $greater);
88 | } @else {
89 | $seed-map: nth($maps, ceil(length($maps) / 2));
90 |
91 | $seed-value: map-get-nested($seed-map, $keys...);
92 |
93 | @each $map in $maps {
94 | $curr-value: map-get-nested($map, $keys...);
95 |
96 | @if $curr-value == $seed-value {
97 | $equal: append($equal, $map);
98 | } @else if $curr-value < $seed-value {
99 | @if $maps-sort-dir == "asc" {
100 | $less: append($less, $map);
101 | } @else {
102 | $greater: append($greater, $map);
103 | }
104 | } @else {
105 | @if $maps-sort-dir == "asc" {
106 | $greater: append($greater, $map);
107 | } @else {
108 | $less: append($less, $map);
109 | }
110 | }
111 | }
112 |
113 | $less: maps-sort($less, $keys...);
114 | $greater: maps-sort($greater, $keys...);
115 |
116 | @return join(join($less, $equal), $greater);
117 | }
118 | }
119 |
120 | @return $maps;
121 | }
122 |
--------------------------------------------------------------------------------
/examples/material/css-gridish/scss/_utilities.scss:
--------------------------------------------------------------------------------
1 | @import "functions";
2 | @import "values";
3 | @import "variables";
4 |
5 | /// Function returns the value for a given breakpoint.
6 | /// @param {String} $breakpointName Breakpoint name.
7 | /// @return {Length} The breakpoint value in rems.
8 | @function get-breakpoint-value($breakpointName) {
9 | $breakpointValue: map-deep-get(
10 | $breakpointsAndArtboards,
11 | $breakpointName,
12 | "breakpoint"
13 | );
14 |
15 | @return $breakpointValue * 1rem;
16 | }
17 |
18 | /// Returns a calc() expression that represents a fluid width at a given breakpoint.
19 | /// @param {String} $breakpointName A valid breakpoint.
20 | /// @param {Number} $columnSpan The number of columns to span across.
21 | /// @return {Length} A calc() expression representing fluid width.
22 | /// @example scss
23 | /// button {
24 | /// @include media-query('sm') {
25 | /// max-width: get-fluid-size('sm', 1);
26 | /// }
27 | /// }
28 | /// @output css
29 | /// @media screen and (min-width: 20rem) {
30 | /// button {
31 | /// max-width: 25vw;
32 | /// }
33 | /// }
34 | @function get-fluid-size($breakpointName, $columnSpan) {
35 | $breakpoint: map-get($breakpointsAndArtboards, $breakpointName);
36 |
37 | @if ($breakpoint == null or type-of($breakpoint) != "map") {
38 | @error "The provided breakpoint `#{$breakpointName}` is not a valid breakpoint found in breakpoints or extraArtboards in $grid-values. Please double-check your grid configuration.";
39 | }
40 |
41 | $columnTotal: map-get($breakpoint, columns);
42 | $margin: map-get($breakpoint, margin);
43 |
44 | @if ($columnTotal == null or type-of($columnTotal) != "number") {
45 | @error "The provided breakpoint `#{$breakpointName}` needs to have a total number of columns set in $grid-values. Please double-check your grid configuration.";
46 | }
47 |
48 | @if ($columnSpan == null or type-of($columnSpan) != "number") {
49 | @error "The number of columns to span for the breakpoint `#{$breakpointName}` must be a valid number. The provided column span value `#{$columnSpan}` is not a number";
50 | }
51 |
52 | @if ($columnSpan > $columnTotal or $columnSpan <= 0) {
53 | @error "The number of columns to span for the breakpoint `#{$breakpointName}` must be greater than 0 and less than or equal to the total number of columns for this breakpoint. The provided column value `#{$columnSpan}` does not meet this criteria";
54 | }
55 |
56 | $container: 100vw;
57 | // Last breakpoint is a max-width and should be a fixed number
58 | @if is-same-breakpoint($breakpoint, $last) {
59 | $container: map-get($breakpoint, breakpoint) * 1rem;
60 | }
61 |
62 | $multiplier: round-decimal($columnSpan / $columnTotal, 4, floor);
63 |
64 | // For IE, we can't have a 0 in the $fluidWidth calc().
65 | @if ($margin == 0) {
66 | @return $container * $multiplier;
67 | }
68 |
69 | @return calc((#{$container} - #{$margin * 2}) * #{$multiplier});
70 | }
71 |
72 | /// Function gets a calculated rem value for a fixed size.
73 | /// @param {Number} $unitQuantity Fixed nondimensional units.
74 | /// @return {Length} A calculated rem value.
75 | /// @example scss
76 | /// button {
77 | /// @include media-query('sm') {
78 | /// max-width: get-fixed-size(10);
79 | /// }
80 | /// }
81 | /// @output css
82 | /// @media screen and (min-width: 20rem) {
83 | /// button {
84 | /// max-width: 5rem;
85 | /// }
86 | /// }
87 | @function get-fixed-size($unitQuantity) {
88 | // Derive the base unit from the current row height of the grid
89 | $fixedUnit: map-get($grid-values, "rowHeight");
90 |
91 | @if ($fixedUnit == null or type-of($fixedUnit) != "number") {
92 | @error "The rowHeight in $grid-values needs be a valid number. Please check your grid configuration.";
93 | }
94 |
95 | @if ($unitQuantity == null or type-of($unitQuantity) != "number") {
96 | @error "The provided fixed value `#{$unitQuantity}` to get-fixed-size() needs to be a valid number greater than 0.";
97 | }
98 |
99 | @return $unitQuantity * $fixedUnit * 1rem;
100 | }
101 |
102 | /// Utility for declaring mobile-first media queries.
103 | /// @param {String} $breakpointName The name of the breakpoint to set its width value to media query.
104 | @mixin media-query($breakpointName) {
105 | $breakpointValue: get-breakpoint-value($breakpointName);
106 | @if $breakpointValue == map-get($first, breakpoint) {
107 | @content;
108 | } @else {
109 | @media screen and (min-width: #{$breakpointValue}) {
110 | @content;
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/examples/material/css-gridish/scss/_values.scss:
--------------------------------------------------------------------------------
1 | $grid-values: (
2 | prefix: material,
3 | breakpoints: (
4 | xsmall: (
5 | breakpoint: 22.5,
6 | columns: 4,
7 | gutter: 1rem,
8 | margin: 0
9 | ),
10 | small: (
11 | breakpoint: 37.5,
12 | columns: 8,
13 | gutter: 1rem,
14 | margin: 0
15 | ),
16 | medium: (
17 | breakpoint: 64,
18 | columns: 12,
19 | gutter: 2rem,
20 | margin: 0
21 | ),
22 | xlarge: (
23 | breakpoint: 120,
24 | columns: 12,
25 | gutter: 2rem,
26 | margin: 0
27 | )
28 | ),
29 | extraArtboards: (
30 | large: 90
31 | ),
32 | rem: 16,
33 | rowHeight: 0.5,
34 | rows: 30,
35 | paths: null
36 | );
--------------------------------------------------------------------------------
/examples/material/css-gridish/scss/_variables.scss:
--------------------------------------------------------------------------------
1 | @import "values";
2 |
3 | $prefix: gridish !default;
4 | @if map-get($grid-values, "prefix") and $prefix == "gridish" {
5 | $prefix: map-get($grid-values, "prefix");
6 | }
7 | $extraBreakpoints: () !default;
8 | $breakpoints: add-padding(map-get($grid-values, "breakpoints"));
9 | $first: nth(nth($breakpoints, 1), 2);
10 | $last: nth(nth($breakpoints, -1), 2);
11 | $includeFlexFallback: false !default;
12 | $rowHeight: map-get($grid-values, "rowHeight");
13 | $rows: map-get($grid-values, "rows");
14 | $extraArtboards: map-get($grid-values, "extraArtboards");
15 | $allBreakpoints: all-breakpoints(
16 | $breakpoints,
17 | $extraBreakpoints,
18 | $first,
19 | $last
20 | );
21 | $breakpointsAndArtboards: all-breakpoints(
22 | $breakpoints,
23 | $extraArtboards,
24 | $first,
25 | $last
26 | );
27 |
--------------------------------------------------------------------------------
/examples/material/css-gridish/scss/material-grid-legacy.scss:
--------------------------------------------------------------------------------
1 | $includeFlexFallback: true;
2 | @import "core.scss";
3 |
4 | @supports (display: grid) {
5 | .#{$prefix}-grid > *,
6 | .#{$prefix}-grid > [class*="#{$prefix}-grid__col--"] {
7 | min-width: initial;
8 | max-width: initial;
9 | width: initial;
10 |
11 | &.#{$prefix}-grid {
12 | display: grid;
13 | }
14 | }
15 |
16 | .#{$prefix}-grid > [class*="#{$prefix}-grid__height--"] {
17 | height: unset;
18 | max-height: unset;
19 | min-height: initial;
20 | }
21 | }
22 |
23 | .#{$prefix}-grid > script {
24 | display: none;
25 | }
26 |
--------------------------------------------------------------------------------
/examples/material/css-gridish/scss/material-grid.scss:
--------------------------------------------------------------------------------
1 | @import "core.scss";
2 |
--------------------------------------------------------------------------------
/examples/material/example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
111 |
112 |
113 |
114 |
128 |
129 |
146 |
147 | Cards
148 |
149 |
150 | Card Title
151 | Card subtitle or description goes here.
152 |
153 |
154 | Card Title
155 | Card subtitle or description goes here.
156 |
157 |
158 | Card Title
159 | Card subtitle or description goes here.
160 |
161 |
162 | Card Title
163 | Card subtitle or description goes here.
164 |
165 |
166 | Card Title
167 | Card subtitle or description goes here.
168 |
169 |
170 | Card Title
171 | Card subtitle or description goes here.
172 |
173 |
174 | Card Title
175 | Card subtitle or description goes here.
176 |
177 |
178 | Card Title
179 | Card subtitle or description goes here.
180 |
181 |
182 |
183 |
184 |
185 |
--------------------------------------------------------------------------------
/examples/material/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
32 |
33 |
34 |
35 |
36 |
CSS Gridish
37 |
Material Example
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
Learn more about
46 | CSS Gridish.
47 |
48 |
Also check out our examples of CSS Gridish making grid code for
49 | Bootstrap and
50 | Carbon.
51 |
52 |
53 |
54 |
79 |
80 |
--------------------------------------------------------------------------------
/examples/material/intro.md:
--------------------------------------------------------------------------------
1 | # Material Design Grid
2 |
3 | An example of [CSS Gridish](../../../README.md) generating CSS Grid code, fallback flexbox code, dev documentation, and Sketch files based on the [Material breakpoint system.](https://material.io/guidelines/layout/responsive-ui.html)
4 |
--------------------------------------------------------------------------------
/examples/material/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css-gridish-example-carbon",
3 | "version": "0.0.1",
4 | "engines": {
5 | "node": ">=8.2.0"
6 | },
7 | "repository": {
8 | "type": "git",
9 | "url": "git@ibm.com:ibm/css-gridish.git"
10 | },
11 | "author": "James Y. Rauhut ",
12 | "license": "Apache-2.0",
13 | "scripts": {
14 | "build": "node ../../bin/index.js",
15 | "test": "true"
16 | },
17 | "dependencies": {}
18 | }
19 |
--------------------------------------------------------------------------------
/examples/material/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 |
--------------------------------------------------------------------------------
/extension/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2017 IBM
2 | Licensed under the Apache License, Version 2.0 (the "License");
3 | you may not use this file except in compliance with the License.
4 | You may obtain a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS,
10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | See the License for the specific language governing permissions and
12 | limitations under the License.
--------------------------------------------------------------------------------
/extension/icons/icon128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/extension/icons/icon128.png
--------------------------------------------------------------------------------
/extension/icons/icon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/extension/icons/icon16.png
--------------------------------------------------------------------------------
/extension/icons/icon19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/extension/icons/icon19.png
--------------------------------------------------------------------------------
/extension/icons/icon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/extension/icons/icon32.png
--------------------------------------------------------------------------------
/extension/icons/icon48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/extension/icons/icon48.png
--------------------------------------------------------------------------------
/extension/icons/icon64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/extension/icons/icon64.png
--------------------------------------------------------------------------------
/extension/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "CSS Gridish",
3 | "version": "1.0.1",
4 | "manifest_version": 2,
5 | "description":
6 | "Check how a webpage aligns with your grid design generated by CSS Gridish",
7 | "homepage_url": "https://github.com/ibm/css-gridish",
8 | "icons": {
9 | "16": "icons/icon16.png",
10 | "48": "icons/icon48.png",
11 | "128": "icons/icon128.png"
12 | },
13 | "browser_action": {
14 | "default_title": "CSS Gridish",
15 | "default_popup": "src/browserAction/browserAction.html"
16 | },
17 | "content_scripts": [
18 | {
19 | "matches": ["http://*/*", "https://*/*"],
20 | "css": ["src/inject/inject.css"]
21 | },
22 | {
23 | "matches": ["http://*/*", "https://*/*"],
24 | "js": ["src/inject/inject.js"]
25 | }
26 | ],
27 | "permissions": ["tabs", "storage", "http://*/*", "https://*/*"]
28 | }
29 |
--------------------------------------------------------------------------------
/extension/src/browserAction/browserAction.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CSS Gridish
6 |
7 |
26 |
27 |
28 |
29 |
30 |
CSS Gridish
31 |
32 |
Upload your grid’s css-gridish.json to check the alignment of a webpage.
33 |
Press CTRL+G to toggle your grid, CTRL+L to toggle your layout.
34 |
Note: Refreshing already open webpages is necessary after installing CSS Gridish.
35 |
Change grid by uploading new css-gridish.json:
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/extension/src/browserAction/browserAction.js:
--------------------------------------------------------------------------------
1 | function configChange() {
2 | var fileReader = new FileReader();
3 | var success = function(content) {
4 | chrome.storage.sync.set({ cssGridish: JSON.parse(content) }, function() {
5 | console.log("Storage Succesful");
6 | });
7 | };
8 |
9 | fileReader.onload = function(evt) {
10 | success(evt.target.result);
11 | };
12 | fileReader.readAsText(document.getElementById("upload").files[0]);
13 | }
14 |
15 | document.getElementById("upload").addEventListener("change", configChange);
16 |
17 | chrome.storage.sync.get("cssGridish", function(object) {
18 | var gridConfig = object.cssGridish;
19 | if (object.cssGridish === {} || object.cssGridish === undefined) {
20 | chrome.storage.sync.set({
21 | cssGridish: {
22 | prefix: "bx",
23 | breakpoints: {
24 | sm: {
25 | breakpoint: 20,
26 | columns: 12,
27 | gutter: "1.250rem",
28 | margin: "5vw"
29 | },
30 | xxl: {
31 | breakpoint: 100,
32 | columns: 12,
33 | gutter: "1.250rem",
34 | margin: "5vw"
35 | }
36 | },
37 | extraArtboards: {
38 | md: 48,
39 | lg: 62,
40 | xl: 75
41 | },
42 | rem: 16,
43 | rowHeight: 0.5,
44 | rows: 30,
45 | paths: {
46 | intro: "intro.md"
47 | }
48 | }
49 | });
50 | }
51 |
52 | document.getElementById("currentGrid").innerText =
53 | "Current grid: " + gridConfig.prefix + "-grid";
54 | });
55 |
56 | chrome.storage.onChanged.addListener(function(changes, area) {
57 | if (changes.cssGridish) {
58 | document.getElementById("currentGrid").innerText =
59 | "Current grid: " + changes.cssGridish.newValue.prefix + "-grid";
60 | }
61 | });
62 |
--------------------------------------------------------------------------------
/extension/src/inject/inject.css:
--------------------------------------------------------------------------------
1 | .css-gridish-checker {
2 | left: 0;
3 | height: 100vh !important;
4 | margin: 0 auto;
5 | pointer-events: none;
6 | position: fixed;
7 | right: 0;
8 | top: 0;
9 | width: 100vw !important;
10 | z-index: 9999;
11 | }
12 |
13 | .css-gridish-checker__grid,
14 | .css-gridish-checker__layout {
15 | height: 100%;
16 | position: absolute;
17 | width: 100%;
18 | }
19 |
20 | .css-gridish-checker__grid {
21 | background: linear-gradient(to right, #c0c6cd 1px, transparent 1px),
22 | linear-gradient(to bottom, #c0c6cd 1px, transparent 1px);
23 | }
24 |
25 | .css-gridish-checker__layout {
26 | box-sizing: border-box;
27 | display: flex;
28 | }
29 |
30 | .css-gridish-checker__layout__col {
31 | background: #b8c1c1;
32 | display: none;
33 | flex: 1;
34 | opacity: 0.75;
35 | }
36 |
--------------------------------------------------------------------------------
/extension/src/inject/inject.js:
--------------------------------------------------------------------------------
1 | var checker = document.createElement("div");
2 | checker.className = "css-gridish-checker";
3 |
4 | var checkerStyle = document.createElement("style");
5 | checker.appendChild(checkerStyle);
6 |
7 | var grid = document.createElement("div");
8 | grid.className = "css-gridish-checker__grid";
9 |
10 | var layout = document.createElement("div");
11 | layout.className = "css-gridish-checker__layout";
12 |
13 | function createCol(breakpoint) {
14 | var col = document.createElement("div");
15 | col.className =
16 | "css-gridish-checker__layout__col css-gridish-checker__layout__col--" +
17 | breakpoint;
18 | return col;
19 | }
20 |
21 | function createGrid(gridConfig) {
22 | checkerStyle.innerHTML = "";
23 | grid.innerHTML = "";
24 | layout.innerHTML = "";
25 |
26 | var largestBreakpoint = Object.values(gridConfig.breakpoints)
27 | .map(breakpoint => breakpoint.breakpoint)
28 | .sort((a, b) => a - b)
29 | .slice(-1)[0];
30 | checker.setAttribute(
31 | "style",
32 | "font-size: " +
33 | gridConfig.rem +
34 | "px; max-width: " +
35 | largestBreakpoint +
36 | "em;"
37 | );
38 |
39 | // rowHeight
40 | var rowHeight = gridConfig.rowHeight;
41 | grid.setAttribute(
42 | "style",
43 | "background-size: " + rowHeight + "rem " + rowHeight + "rem;"
44 | );
45 |
46 | // breakpoints
47 | var breakpoints = Object.values(gridConfig.breakpoints)
48 | .map((item, index) => {
49 | var result = item;
50 | result.name = Object.keys(gridConfig.breakpoints)[index];
51 | return result;
52 | })
53 | .sort((a, b) => a.breakpoint - b.breakpoint);
54 | for (var i = 0; i < breakpoints.length; i++) {
55 | var mediaQuery = 0;
56 | var previous = 0;
57 | if (i > 0) {
58 | previous = breakpoints[i - 1].columns;
59 | mediaQuery = breakpoints[i].breakpoint;
60 | }
61 | var newColumns = breakpoints[i].columns - previous;
62 | for (var j = 0; j < newColumns; j++) {
63 | layout.appendChild(createCol(breakpoints[i].name));
64 | }
65 |
66 | checkerStyle.innerHTML =
67 | checkerStyle.innerHTML +
68 | `
69 | @media (min-width: ${mediaQuery}rem) {
70 | .css-gridish-checker__layout {
71 | padding: 0 ${breakpoints[i].margin};
72 | }
73 |
74 | .css-gridish-checker__layout__col {
75 | margin: 0 ${parseInt(breakpoints[i].gutter, 10) / 2}${
76 | breakpoints[i].gutter.match(/[a-zA-Z]+/g)[0]
77 | };
78 | }
79 |
80 | .css-gridish-checker__layout__col--${breakpoints[i].name} {
81 | display: initial;
82 | }
83 | }
84 | `;
85 | }
86 | }
87 |
88 | function toggleCSSGridishChecker(e) {
89 | if (e.ctrlKey && e.keyCode == 71) {
90 | if (!checker.contains(grid)) {
91 | checker.appendChild(grid);
92 | } else {
93 | grid.remove();
94 | }
95 | }
96 | if (e.ctrlKey && e.keyCode == 76) {
97 | if (!checker.contains(layout)) {
98 | checker.appendChild(layout);
99 | } else {
100 | layout.remove();
101 | }
102 | }
103 |
104 | if (e.ctrlKey && (e.keyCode == 71 || e.keyCode == 76)) {
105 | if (checker.contains(grid) || checker.contains(layout)) {
106 | document.body.appendChild(checker);
107 | } else {
108 | document.body.removeChild(checker);
109 | }
110 | }
111 | }
112 |
113 | document.addEventListener("keydown", toggleCSSGridishChecker, false);
114 |
115 | chrome.storage.sync.get("cssGridish", function(object) {
116 | var gridConfig = object.cssGridish;
117 | if (object.cssGridish === {} || object.cssGridish === undefined) {
118 | gridConfig = {
119 | prefix: "bx",
120 | breakpoints: {
121 | sm: {
122 | breakpoint: 20,
123 | columns: 12,
124 | gutter: "1.250rem",
125 | margin: "5vw"
126 | },
127 | xxl: {
128 | breakpoint: 100,
129 | columns: 12,
130 | gutter: "1.250rem",
131 | margin: "5vw"
132 | }
133 | },
134 | extraArtboards: {
135 | md: 48,
136 | lg: 62,
137 | xl: 75
138 | },
139 | rem: 16,
140 | rowHeight: 0.5,
141 | rows: 30,
142 | paths: {
143 | intro: "intro.md"
144 | }
145 | };
146 | }
147 |
148 | createGrid(gridConfig);
149 | });
150 |
151 | chrome.storage.onChanged.addListener(function(changes, area) {
152 | if (changes.cssGridish) {
153 | createGrid(changes.cssGridish.newValue);
154 | }
155 | });
156 |
--------------------------------------------------------------------------------
/graphics/configDiagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/graphics/configDiagram.png
--------------------------------------------------------------------------------
/graphics/graphics.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/graphics/graphics.sketch
--------------------------------------------------------------------------------
/graphics/gridish.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/graphics/gridish.png
--------------------------------------------------------------------------------
/graphics/gridish_3times.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/graphics/gridish_3times.gif
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const browserSync = require("browser-sync").create(),
4 | gulp = require("gulp"),
5 | run = require("gulp-run");
6 |
7 | gulp.task("build", function() {
8 | return run("npm run build").exec();
9 | });
10 |
11 | gulp.task("build:examples", function() {
12 | return run("npm run build:examples").exec();
13 | });
14 |
15 | gulp.task("refresh", ["build"], function(done) {
16 | browserSync.reload();
17 | done();
18 | });
19 |
20 | gulp.task("refresh:examples", ["build:examples"], function(done) {
21 | browserSync.reload();
22 | done();
23 | });
24 |
25 | gulp.task("watch", function() {
26 | browserSync.init({
27 | server: {
28 | baseDir: "."
29 | }
30 | });
31 |
32 | gulp.watch(["**/*.html"]).on("change", browserSync.reload);
33 | gulp.watch("src/**/*", ["refresh"]);
34 | gulp.watch("examples/**/*.json", ["refresh:examples"]);
35 | });
36 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | CSS Gridish
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
175 |
176 |
177 |
178 |
179 |

180 |
181 |
182 | CSS Gridish takes design specs of your product’s grid and builds out several resources for your team to use:
183 |
184 | - - Sketch file with artboards and grid/layout settings for designers
185 | - - CSS/SCSS code using CSS Grid with a CSS Flexbox fallback for developers
186 | - -
187 | Google Chrome extension for anyone to check a webpage’s alignment
189 |
190 |
191 |
196 |
201 |
206 |
207 |
208 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css-gridish",
3 | "version": "2.0.0",
4 | "description":
5 | "Automatically build your grid design’s CSS Grid code, CSS Flexbox fallback code, Sketch artboards, and Chrome extension.",
6 | "engines": {
7 | "node": ">=8.2.0"
8 | },
9 | "main": "bin/index.js",
10 | "repository": {
11 | "type": "git",
12 | "url": "git@ibm.com:ibm/css-gridish.git"
13 | },
14 | "author": "James Y. Rauhut ",
15 | "license": "Apache-2.0",
16 | "dependencies": {
17 | "del": "^3.0.0",
18 | "gulp": "^3.9.1",
19 | "gulp-clean-css": "^3.9.2",
20 | "gulp-json-editor": "^2.2.1",
21 | "gulp-rename": "^1.2.2",
22 | "gulp-sass": "^3.1.0",
23 | "gulp-zip": "^4.1.0",
24 | "handlebars": "^4.0.11",
25 | "json-sass": "^1.3.5",
26 | "through2-map": "^3.0.0",
27 | "vinyl-paths": "^2.1.0",
28 | "vinyl-source-stream": "^2.0.0"
29 | },
30 | "devDependencies": {
31 | "babel-cli": "^6.26.0",
32 | "babel-plugin-transform-object-rest-spread": "^6.26.0",
33 | "babel-preset-env": "^1.6.1",
34 | "browser-sync": "^2.23.5",
35 | "gulp-debug": "^3.2.0",
36 | "gulp-run": "^1.7.1"
37 | },
38 | "scripts": {
39 | "build": "npm run build:src && npm run build:examples",
40 | "build:src":
41 | "cp -a src/. bin/ && babel src/index.js --out-file ./bin/index.js",
42 | "build:examples":
43 | "npm run build --prefix ./examples/bootstrap && npm run build --prefix ./examples/carbon && npm run build --prefix ./examples/material",
44 | "dev": "gulp watch",
45 | "start": "node bin/css-gridish.js",
46 | "test": "true"
47 | },
48 | "bin": {
49 | "css-gridish": "bin/index.js"
50 | },
51 | "keywords": ["css grid", "css flexbox", "css", "sass", "design system"],
52 | "babel": {
53 | "plugins": ["transform-object-rest-spread"],
54 | "presets": [
55 | [
56 | "env",
57 | {
58 | "targets": {
59 | "node": "6.10"
60 | }
61 | }
62 | ]
63 | ]
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const gulp = require("gulp"),
3 | cleanCSS = require("gulp-clean-css"),
4 | del = require("del"),
5 | fs = require("fs"),
6 | handlebars = require("handlebars"),
7 | jeditor = require("gulp-json-editor"),
8 | jsonSass = require("json-sass"),
9 | map = require("through2-map"),
10 | rename = require("gulp-rename"),
11 | sass = require("gulp-sass"),
12 | source = require("vinyl-source-stream"),
13 | vinylPaths = require("vinyl-paths"),
14 | zip = require("gulp-zip");
15 |
16 | const dirRoot = process.cwd();
17 | const routeConfig = `${dirRoot}/css-gridish.json`;
18 | const config = require(routeConfig);
19 | const intro =
20 | config.paths !== undefined && config.paths.intro !== undefined
21 | ? fs.readFileSync(`${dirRoot}/${config.paths.intro}`, "utf8")
22 | : "";
23 | const route =
24 | config.paths !== undefined && config.paths.route !== undefined
25 | ? config.paths.route
26 | : "css-gridish";
27 | const dirDest = `${dirRoot}/${route}`;
28 | const dirDestCss = `${dirDest}/\css`;
29 | const dirDestDesign = `${__dirname}/css-gridish-design.json`;
30 | const dirDestScss = `${dirDest}/s\css`;
31 | const dirDestSketch = `${dirDest}/sketch`;
32 | const prefix = config.prefix ? config.prefix : "gridish";
33 |
34 | const artboard = require(`${__dirname}/sketch/artboard.json`);
35 |
36 | const parseUnit = function(value, width) {
37 | let parsed = value;
38 | if (value !== 0) {
39 | if (value.includes("vw")) {
40 | parsed = value.slice(0, -2) * width * 0.01;
41 | } else if (value.includes("rem")) {
42 | parsed = value.slice(0, -3) * config.rem;
43 | } else if (value.includes("px")) {
44 | parsed = value.slice(0, -2);
45 | } else if (value.includes("%")) {
46 | parsed = value.slice(0, -1) * width * 0.01;
47 | }
48 | }
49 | return parsed;
50 | };
51 |
52 | handlebars.registerHelper("length", function(json) {
53 | return Object.keys(json).length;
54 | });
55 |
56 | handlebars.registerHelper("math", function(lvalue, operator, rvalue, options) {
57 | lvalue = parseFloat(lvalue);
58 | rvalue = parseFloat(rvalue);
59 |
60 | return {
61 | "+": lvalue + rvalue,
62 | "-": lvalue - rvalue,
63 | "*": lvalue * rvalue,
64 | "/": lvalue / rvalue,
65 | "%": lvalue % rvalue
66 | }[operator];
67 | });
68 |
69 | gulp.task("clean", function() {
70 | return del([dirDestCss, dirDestScss, `${dirDest}/${prefix}-grid.sketch`]);
71 | });
72 |
73 | gulp.task("css", ["scssRenameLegacy"], function() {
74 | return gulp
75 | .src(`${dirDestScss}/${prefix}-grid.s\css`)
76 | .pipe(sass().on("error", sass.logError))
77 | .pipe(rename(`${prefix}-grid.\css`))
78 | .pipe(gulp.dest(dirDestCss))
79 | .pipe(
80 | cleanCSS({
81 | level: 2
82 | })
83 | )
84 | .pipe(rename(`${prefix}-grid.min.\css`))
85 | .pipe(gulp.dest(dirDestCss));
86 | });
87 |
88 | gulp.task("css-legacy", ["css"], function() {
89 | return gulp
90 | .src(`${dirDestScss}/${prefix}-grid-legacy.s\css`)
91 | .pipe(sass().on("error", sass.logError))
92 | .pipe(rename(`${prefix}-grid-legacy.\css`))
93 | .pipe(gulp.dest(dirDestCss))
94 | .pipe(
95 | cleanCSS({
96 | level: 2
97 | })
98 | )
99 | .pipe(rename(`${prefix}-grid-legacy.min.\css`))
100 | .pipe(gulp.dest(dirDestCss));
101 | });
102 |
103 | gulp.task("docs", ["css-legacy"], function() {
104 | return gulp
105 | .src(`${__dirname}/docs/*.hbs`)
106 | .pipe(
107 | map.obj(chunk => {
108 | var template = handlebars.compile(chunk.contents.toString());
109 | chunk.contents = new Buffer(
110 | template({
111 | config: {
112 | ...config,
113 | classBreakpoints: Object.keys(config.breakpoints).slice(0, -1),
114 | intro
115 | }
116 | })
117 | );
118 | return chunk;
119 | })
120 | )
121 | .pipe(
122 | rename(path => {
123 | // a template file of the form AAAA.BBB.hbs produces output file AAAA.BBB
124 | var dot = path.basename.lastIndexOf(".");
125 | path.extname = path.basename.substring(dot);
126 | path.basename = path.basename.substring(0, dot);
127 | })
128 | )
129 | .pipe(gulp.dest(dirDest));
130 | });
131 |
132 | gulp.task("scss", ["valuesClean"], function() {
133 | return gulp.src(`${__dirname}/scss/**/*.s\css`).pipe(gulp.dest(dirDestScss));
134 | });
135 |
136 | gulp.task("scssRename", ["scss"], function() {
137 | return gulp
138 | .src(`${dirDestScss}/gridish-grid.s\css`)
139 | .pipe(vinylPaths(del))
140 | .pipe(rename(`${prefix}-grid.s\css`))
141 | .pipe(gulp.dest(dirDestScss));
142 | });
143 |
144 | gulp.task("scssRenameLegacy", ["scssRename"], function() {
145 | return gulp
146 | .src(`${dirDestScss}/gridish-grid-legacy.s\css`)
147 | .pipe(vinylPaths(del))
148 | .pipe(rename(`${prefix}-grid-legacy.s\css`))
149 | .pipe(gulp.dest(dirDestScss));
150 | });
151 |
152 | gulp.task("sketchClean", ["sketchZip"], function() {
153 | return del([dirDestSketch]);
154 | });
155 |
156 | gulp.task("sketchFiles", ["docs"], function() {
157 | return gulp
158 | .src([
159 | `${__dirname}/sketch/files/**/*`,
160 | `!${__dirname}/sketch/files/pages/BC333699-815E-4E1B-9816-9836EDA5B291.json`
161 | ])
162 | .pipe(gulp.dest(dirDestSketch));
163 | });
164 |
165 | gulp.task("sketchPage", ["sketchFiles"], function() {
166 | // Add breakpoint values to extra artboards
167 | const originalBreakpoints = config.breakpoints;
168 | let allBreakpoints = originalBreakpoints;
169 | for (let i = 0; i < Object.values(config.extraArtboards).length; i++) {
170 | const name = Object.keys(config.extraArtboards)[i];
171 | const value = Object.values(config.extraArtboards)[i];
172 | let found = false;
173 | for (let j = 0; j < Object.values(originalBreakpoints).length; j++) {
174 | // should catch at max
175 | if (
176 | Object.values(originalBreakpoints)[j + 1] !== undefined &&
177 | Object.values(originalBreakpoints)[j + 1].breakpoint > value &&
178 | !found
179 | ) {
180 | allBreakpoints[name] = {
181 | ...Object.values(originalBreakpoints)[j],
182 | breakpoint: value
183 | };
184 | found = true;
185 | } else if (Object.values(originalBreakpoints)[i + 1] === undefined) {
186 | allBreakpoints[name] = {
187 | ...Object.values(originalBreakpoints)[i],
188 | breakpoint: value
189 | };
190 | }
191 | }
192 | }
193 |
194 | // Sort all breakpoints by size
195 | let sorted = Object.values(allBreakpoints);
196 | for (let i = 0; i < sorted.length; i++) {
197 | sorted[i] = {
198 | ...sorted[i],
199 | name: Object.keys(allBreakpoints)[i]
200 | };
201 | }
202 | sorted = sorted.sort(function(a, b) {
203 | return a.breakpoint - b.breakpoint;
204 | });
205 |
206 | // Make artboards for each breakpoint
207 | let layers = [];
208 | let x = 0;
209 | for (let i = 0; i < sorted.length; i++) {
210 | x = i > 0 ? x + (sorted[i - 1].breakpoint + 1) * config.rem : 0;
211 | const values = sorted[i];
212 | const width = values.breakpoint * config.rem;
213 | const margin = parseUnit(values.margin, width);
214 | const gutter = parseUnit(values.gutter, width);
215 | const gridWidth = width - margin * 2;
216 | const gutterWidth = gutter;
217 |
218 | layers.push({
219 | ...artboard,
220 | name: `${values.name}-${width}px-${values.columns}`,
221 | do_objectID: artboard.do_objectID.slice(0, -1) + i,
222 | frame: {
223 | ...artboard.frame,
224 | width,
225 | x
226 | },
227 | grid: {
228 | ...artboard.grid,
229 | gridSize: config.rowHeight * config.rem
230 | },
231 | layout: {
232 | ...artboard.layout,
233 | columnWidth:
234 | (gridWidth - gutterWidth * values.columns) / values.columns,
235 | gutterWidth,
236 | horizontalOffset: margin,
237 | numberOfColumns: values.columns,
238 | totalWidth: gridWidth
239 | }
240 | });
241 | }
242 | return gulp
243 | .src(
244 | `${__dirname}/sketch/files/pages/BC333699-815E-4E1B-9816-9836EDA5B291.json`
245 | )
246 | .pipe(
247 | jeditor({
248 | layers
249 | })
250 | )
251 | .pipe(gulp.dest(`${dirDestSketch}/pages`));
252 | });
253 |
254 | gulp.task("sketchZip", ["sketchPage"], function() {
255 | return gulp
256 | .src(`${dirDestSketch}/**/*`)
257 | .pipe(zip(`${prefix}-grid.zip`))
258 | .pipe(rename(`${prefix}-grid.sketch`))
259 | .pipe(vinylPaths(del))
260 | .pipe(gulp.dest(dirDest));
261 | });
262 |
263 | gulp.task("values", ["valuesPrep"], function() {
264 | return fs
265 | .createReadStream(dirDestDesign)
266 | .pipe(
267 | jsonSass({
268 | prefix: "$grid-values: "
269 | })
270 | )
271 | .pipe(source(routeConfig))
272 | .pipe(rename("_values.scss"))
273 | .pipe(gulp.dest(dirDestScss));
274 | });
275 |
276 | gulp.task("valuesClean", ["values"], function() {
277 | return fs.unlinkSync(dirDestDesign);
278 | });
279 |
280 | gulp.task("valuesPrep", ["clean"], function() {
281 | return fs.writeFileSync(
282 | dirDestDesign,
283 | JSON.stringify({
284 | ...config,
285 | paths: null
286 | })
287 | );
288 | });
289 |
290 | gulp.task("default", ["sketchClean"], function() {
291 | console.log(
292 | `CSS Gridish finished building your ${prefix} grid in ${dirDest}! 🏁`
293 | );
294 | });
295 |
296 | gulp.start("default");
297 |
--------------------------------------------------------------------------------
/src/scss/_core.scss:
--------------------------------------------------------------------------------
1 | @import "functions.scss";
2 | @import "mixins.scss";
3 | @import "variables.scss";
4 | @import "utilities.scss";
5 |
6 | html {
7 | font-size: map-get($grid-values, "rem") * 1px;
8 | }
9 |
10 | body {
11 | margin: 0;
12 | }
13 |
14 | .#{$prefix}-container {
15 | box-sizing: border-box;
16 | margin-left: auto;
17 | margin-right: auto;
18 | max-width: #{map-get($last, breakpoint)}rem;
19 | overflow-x: hidden;
20 | width: 100vw;
21 | }
22 |
23 | .#{$prefix}-container--left {
24 | margin-left: 0;
25 | }
26 |
27 | .#{$prefix}-container--right {
28 | margin-right: 0;
29 | }
30 |
31 | .#{$prefix}-grid {
32 | align-items: flex-start;
33 | box-sizing: border-box;
34 | @if $includeFlexFallback {
35 | display: flex;
36 | }
37 | display: grid;
38 | flex-wrap: wrap;
39 | position: relative;
40 |
41 | > * {
42 | box-sizing: border-box;
43 |
44 | :last-child,
45 | :last-child > :last-child,
46 | :last-child > :last-child > :last-child {
47 | margin-bottom: 0;
48 | }
49 | }
50 | }
51 |
52 | [class*="#{$prefix}-padding"] {
53 | box-sizing: border-box;
54 | }
55 |
56 | // Rules needed in legacy, but needed to change in CSS Grid
57 | @if $includeFlexFallback {
58 | .#{$prefix}-grid > * {
59 | width: 100%;
60 | }
61 |
62 | @supports (display: grid) {
63 | .#{$prefix}-grid {
64 | align-items: unset;
65 | }
66 |
67 | .#{$prefix}-grid > * {
68 | width: initial;
69 | }
70 | }
71 | }
72 |
73 | // Rules not needed in legacy, but needed in CSS Grid
74 | @supports (display: grid) {
75 | .#{$prefix}-grid > * {
76 | height: 100%;
77 | }
78 | }
79 |
80 | @include grid-legacy-wrapper($includeFlexFallback) {
81 | :root {
82 | @include grid-heights-fixed($rows);
83 | }
84 | }
85 |
86 | @each $name, $breakpoint in $allBreakpoints {
87 | @include media-query($name) {
88 | @if is-same-breakpoint($breakpoint, $last) == false {
89 | @include grid-legacy-heights($name);
90 | }
91 | @include grid-legacy-zeros($breakpoint, $name);
92 | @include grid-padding($breakpoint);
93 | @include grid($breakpoint, $name);
94 | @include grid-legacy-columns($breakpoint, $name);
95 |
96 | // Wrap all bleed/break classes and css variables in a CSS Grid support query
97 | @include grid-legacy-wrapper($includeFlexFallback) {
98 | @include grid-margin($breakpoint, $name);
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/scss/_functions.scss:
--------------------------------------------------------------------------------
1 | @import "sass-list-maps";
2 |
3 | // Transform the gutter property into a padding property for web
4 | @function add-padding($breakpoints) {
5 | $cleanBreakpoints: ();
6 | @each $name, $breakpoint in $breakpoints {
7 | $cleanBreakpoints: map-merge(
8 | $cleanBreakpoints,
9 | (
10 | $name:
11 | map-merge($breakpoint, (padding: map-get($breakpoint, gutter) / 2))
12 | )
13 | );
14 | }
15 |
16 | @return $cleanBreakpoints;
17 | }
18 |
19 | // Merge standard and custom breakpoints into list
20 | @function all-breakpoints($breakpoints, $extraBreakpoints, $first, $last) {
21 | $allBreakpoints: $breakpoints;
22 | @each $currentBreakpoint in $extraBreakpoints {
23 | $extraBreakpointName: nth($currentBreakpoint, 1);
24 | $extraBreakpointWidth: nth($currentBreakpoint, 2);
25 | $found: false;
26 | $match: null;
27 | @each $majorBreakpoint in $breakpoints {
28 | @if $found == false {
29 | @if map-get(nth($majorBreakpoint, 2), breakpoint) >
30 | $extraBreakpointWidth
31 | {
32 | $found: true;
33 | } @else {
34 | $match: $majorBreakpoint;
35 | }
36 | }
37 | }
38 | @if $extraBreakpointWidth > map-get($last, breakpoint) {
39 | $match: (
40 | last,
41 | $last
42 | );
43 | }
44 | @if $extraBreakpointWidth < map-get($first, breakpoint) {
45 | $match: (
46 | first,
47 | $first
48 | );
49 | }
50 |
51 | $newBreakpoint: map-merge(
52 | nth($match, 2),
53 | (breakpoint: $extraBreakpointWidth)
54 | );
55 | $currentBreakpoint: (
56 | $extraBreakpointName:
57 | map-merge(nth($match, 2), (breakpoint: $extraBreakpointWidth))
58 | );
59 | $allBreakpoints: map-merge($allBreakpoints, $currentBreakpoint);
60 | }
61 |
62 | @return maps-sort($allBreakpoints, breakpoint);
63 | }
64 |
65 | @function is-same-breakpoint($a, $b) {
66 | @return map-get($a, breakpoint) == map-get($b, breakpoint);
67 | }
68 |
69 | /// Traverse maps and retrieve deeply nested values: https://css-tricks.com/snippets/sass/deep-getset-maps/
70 | /// @author Hugo Giraudel
71 | /// @param {Map} $map A sass map and any number of keys.
72 | /// @param {*} $keys Nested values.
73 | /// @return Nested values or nested map.
74 | @function map-deep-get($map, $keys...) {
75 | @each $key in $keys {
76 | $map: map-get($map, $key);
77 | }
78 | @return $map;
79 | }
80 |
81 | // _decimal.scss | MIT License | gist.github.com/terkel/4373420
82 | @function round-decimal($number, $digits: 0, $mode: round) {
83 | $n: 1;
84 | // $number must be a number
85 | @if type-of($number) != number {
86 | @warn "#{ $number } is not a number.";
87 | @return $number;
88 | }
89 | // $digits must be a unitless number
90 | @if type-of($digits) != number {
91 | @warn "#{ $digits } is not a number.";
92 | @return $number;
93 | } @else if not unitless($digits) {
94 | @warn "#{ $digits } has a unit.";
95 | @return $number;
96 | }
97 | @for $i from 1 through $digits {
98 | $n: $n * 10;
99 | }
100 | @if $mode == round {
101 | @return round($number * $n) / $n;
102 | } @else if $mode == ceil {
103 | @return ceil($number * $n) / $n;
104 | } @else if $mode == floor {
105 | @return floor($number * $n) / $n;
106 | } @else {
107 | @warn "#{ $mode } is undefined keyword.";
108 | @return $number;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Set the width of a grid’s column
2 | @mixin grid($breakpoint, $breakpointName) {
3 | @if (map-get($breakpoint, columns) != null) {
4 | $columnSize: get-fluid-size($breakpointName, 1);
5 |
6 | .#{$prefix}-grid {
7 | @if is-same-breakpoint($breakpoint, $first) {
8 | grid-auto-rows: minmax($rowHeight * 1rem, min-content);
9 | }
10 | grid-template-columns: repeat(auto-fill, $columnSize);
11 |
12 | &.#{$prefix}-grid--fixed-columns {
13 | grid-template-columns: repeat(
14 | auto-fill,
15 | map-get($breakpoint, breakpoint) *
16 | 1rem /
17 | map-get($breakpoint, columns)
18 | );
19 | }
20 |
21 | &.#{$prefix}-grid--fluid-rows {
22 | grid-auto-rows: $columnSize;
23 | }
24 |
25 | @if is-same-breakpoint($breakpoint, $last) == false {
26 | > * {
27 | grid-column: span #{map-get($breakpoint, columns)};
28 | }
29 | }
30 | }
31 | }
32 | }
33 |
34 | // Generate variables for commonly used rows
35 | @mixin grid-heights-fixed($rows) {
36 | @for $i from 1 to $rows {
37 | --#{$prefix}-height-#{$i}: get-fixed-size($i);
38 | }
39 | }
40 |
41 | // Set the width of a grid’s column for legacy grid
42 | @mixin grid-legacy-columns($breakpoint, $name) {
43 | // Do not make class if last media query
44 | @if is-same-breakpoint($breakpoint, $last) == false {
45 | // Loop each breakpoint to insert previous breakpoint classes inside this breakpoint’s media query
46 | // Ex: Make sure .yourPrefix-grid__col--sm--2 has correct sizes in the lg media query
47 | @each $currentName, $currentBreakpoint in $allBreakpoints {
48 | // Check if current breakpoint is not bigger than current media query
49 | @if map-get($breakpoint, breakpoint) >=
50 | map-get($currentBreakpoint, breakpoint)
51 | {
52 | // Loop each column in current breakpoint for new class
53 | // Ex: .yourPrefix-grid__col--sm--1, .yourPrefix-grid__col--sm--2, etc.
54 | @for $i from 1 through map-get($currentBreakpoint, columns) {
55 | $columnMultiplier: $i *
56 | map-get($breakpoint, columns) /
57 | map-get($currentBreakpoint, columns);
58 | $columnSize: get-fluid-size($name, $columnMultiplier);
59 |
60 | $isSecondToLast: is-same-breakpoint(
61 | $breakpoint,
62 | nth(nth($allBreakpoints, length($allBreakpoints) - 1), 2)
63 | );
64 |
65 | $maxColumnSize: get-fluid-size(
66 | nth(nth($allBreakpoints, length($allBreakpoints)), 1),
67 | $columnMultiplier
68 | );
69 |
70 | .#{$prefix}-grid__col--#{$currentName}--#{$i} {
71 | @if $includeFlexFallback {
72 | // If second-to-last media query, apply max-width instead of remaking classes in last media query
73 | @if $isSecondToLast {
74 | max-width: $maxColumnSize;
75 | }
76 | width: $columnSize;
77 | }
78 | grid-column: span #{$columnMultiplier};
79 |
80 | @if is-same-breakpoint($breakpoint, $last) == false {
81 | &.#{$prefix}-grid > *:not([class*="#{$prefix}-grid__col"]) {
82 | grid-column: span #{$i};
83 | }
84 | }
85 | }
86 |
87 | .#{$prefix}-grid--fluid-rows
88 | > .#{$prefix}-grid__height--#{$currentName}--#{$i} {
89 | grid-row: span $i;
90 | @if $includeFlexFallback {
91 | height: $columnSize;
92 | min-height: $columnSize;
93 | // If second-to-last media query, apply max-height instead of remaking classes in last media query
94 | @if $isSecondToLast {
95 | max-height: $maxColumnSize;
96 | }
97 | }
98 | }
99 | }
100 | }
101 | }
102 | }
103 |
104 | @if $includeFlexFallback {
105 | @if is-same-breakpoint($breakpoint, $last) {
106 | [class*="#{$prefix}-grid__col--"] {
107 | min-width: 0;
108 | }
109 | }
110 | }
111 | }
112 |
113 | // Set the height of an item for legacy grid
114 | @mixin grid-legacy-heights($name) {
115 | .#{$prefix}-grid__height--#{$name}--0 {
116 | height: 0;
117 | min-height: 0;
118 | }
119 | @for $i from 1 to $rows {
120 | .#{$prefix}-grid__height--#{$name}--#{$i} {
121 | grid-row: span $i;
122 | @if $includeFlexFallback {
123 | height: get-fixed-size($i);
124 | min-height: get-fixed-size($i);
125 | }
126 | }
127 | }
128 | }
129 |
130 | // If we need legacy grid, wrap this content in support tag
131 | @mixin grid-legacy-wrapper($includeFlexFallback) {
132 | @if $includeFlexFallback {
133 | @supports (display: grid) {
134 | @content;
135 | }
136 | } @else {
137 | @content;
138 | }
139 | }
140 |
141 | // Generate all classes for 0 and 0-only displaying, including custom breakpoints if they exist
142 | @mixin grid-legacy-zeros($breakpoint, $name) {
143 | // Undo previous breakpoint’s 0--only class
144 | @for $i from length($allBreakpoints) * -1 through -1 {
145 | $currentBreakpoint: nth($allBreakpoints, $i);
146 | @if map-get(nth($currentBreakpoint, 2), breakpoint) <
147 | map-get($breakpoint, breakpoint)
148 | {
149 | .#{$prefix}-grid__col--#{nth($currentBreakpoint, 1)}--0--only {
150 | display: block;
151 | }
152 | }
153 | }
154 |
155 | [class*="#{$prefix}-grid__col--#{$name}--"] {
156 | display: block;
157 | }
158 |
159 | .#{$prefix}-grid__col--#{$name}--0,
160 | .#{$prefix}-grid__col--#{$name}--0--only {
161 | display: none;
162 | }
163 | }
164 |
165 | // Set the width of a grid’s margin
166 | // and allow for a child to break out of the grid’s margin
167 | @mixin grid-margin($breakpoint, $name) {
168 | $nameToUse: $name;
169 | $margin: #{map-get($breakpoint, margin)};
170 | $padding: #{map-get($breakpoint, padding)};
171 |
172 | // If last breakpoint, we use the previous breakpoint name
173 | // to treat the last breakpoint as the max-width of the previous breakpoint
174 | @if is-same-breakpoint($breakpoint, $last) == true {
175 | $previousBreakpoint: nth(
176 | $allBreakpoints,
177 | index(map-keys($allBreakpoints), $name) - 1
178 | );
179 | $nameToUse: nth($previousBreakpoint, 1);
180 | }
181 |
182 | // Undo previous breakpoint’s bleeds and breaks
183 | @if is-same-breakpoint($breakpoint, $first) ==
184 | false and
185 | is-same-breakpoint($breakpoint, $last) ==
186 | false
187 | {
188 | $previousBreakpoint: nth(
189 | $allBreakpoints,
190 | index(map-keys($allBreakpoints), $name) - 1
191 | );
192 | $previousName: nth($previousBreakpoint, 1);
193 | $previousMargin: map-get(nth($previousBreakpoint, 2), margin);
194 |
195 | @if $previousMargin !=
196 | null and
197 | $previousMargin !=
198 | 0 and
199 | $previousMargin !=
200 | "0"
201 | {
202 | [class^="#{$prefix}-container__bleed--#{$previousName}"],
203 | [class^="#{$prefix}-container__break--#{$previousName}"] {
204 | margin-left: 0;
205 | margin-right: 0;
206 | padding-left: 0;
207 | padding-right: 0;
208 |
209 | &[class^="#{$prefix}-padding"] {
210 | padding-left: $padding;
211 | padding-right: $padding;
212 | }
213 | }
214 | }
215 | }
216 |
217 | @if $margin != null and $margin != 0 and $margin != "0" {
218 | $marginPlusPadding: calc(#{$margin} + #{$padding});
219 | @if $margin == "0" and $padding == "0" {
220 | $marginPlusPadding: 0;
221 | } @else if $margin == "0" {
222 | $marginPlusPadding: $padding;
223 | } @else if $padding == "0" {
224 | $marginPlusPadding: $margin;
225 | }
226 |
227 | .#{$prefix}-container {
228 | margin-left: auto;
229 | margin-right: auto;
230 | padding-left: $margin;
231 | padding-right: $margin;
232 | }
233 |
234 | .#{$prefix}-container--left {
235 | margin-left: 0;
236 | }
237 |
238 | .#{$prefix}-container--right {
239 | margin-right: 0;
240 | }
241 |
242 | .#{$prefix}-container__bleed--#{$nameToUse},
243 | .#{$prefix}-container__bleed--#{$nameToUse}--left,
244 | .#{$prefix}-container__break--#{$nameToUse},
245 | .#{$prefix}-container__break--#{$nameToUse}--left {
246 | margin-left: -#{$margin};
247 | }
248 |
249 | .#{$prefix}-container__bleed--#{$nameToUse},
250 | .#{$prefix}-container__bleed--#{$nameToUse}--right,
251 | .#{$prefix}-container__break--#{$nameToUse},
252 | .#{$prefix}-container__break--#{$nameToUse}--right {
253 | margin-right: -#{$margin};
254 | }
255 |
256 | .#{$prefix}-container__bleed--#{$nameToUse},
257 | .#{$prefix}-container__bleed--#{$nameToUse}--left {
258 | padding-left: $margin;
259 |
260 | &.#{$prefix}-padding,
261 | &.#{$prefix}-padding--horizontal,
262 | &.#{$prefix}-padding--left {
263 | padding-left: $marginPlusPadding;
264 | }
265 | }
266 |
267 | .#{$prefix}-container__bleed--#{$nameToUse},
268 | .#{$prefix}-container__bleed--#{$nameToUse}--right {
269 | padding-right: $margin;
270 |
271 | &.#{$prefix}-padding,
272 | &.#{$prefix}-padding--horizontal,
273 | &.#{$prefix}-padding--right {
274 | padding-right: $marginPlusPadding;
275 | }
276 | }
277 | }
278 | }
279 |
280 | // Classnames for different padding options
281 | @mixin grid-padding($breakpoint) {
282 | @if (map-get($breakpoint, padding) != null) {
283 | $padding: map-get($breakpoint, padding);
284 |
285 | .#{$prefix}-padding {
286 | padding: $padding;
287 | }
288 |
289 | .#{$prefix}-padding--bottom {
290 | padding-bottom: $padding;
291 | }
292 |
293 | .#{$prefix}-padding--left {
294 | padding-left: $padding;
295 | }
296 |
297 | .#{$prefix}-padding--right {
298 | padding-right: $padding;
299 | }
300 |
301 | .#{$prefix}-padding--top {
302 | padding-top: $padding;
303 | }
304 |
305 | .#{$prefix}-padding--horizontal {
306 | padding-left: $padding;
307 | padding-right: $padding;
308 | }
309 |
310 | .#{$prefix}-padding--vertical {
311 | padding-bottom: $padding;
312 | padding-top: $padding;
313 | }
314 | }
315 | }
316 |
--------------------------------------------------------------------------------
/src/scss/_sass-list-maps.scss:
--------------------------------------------------------------------------------
1 | /// _
2 | /// | |
3 | /// ___ __ _ ___ ___ ______ _ __ ___ __ _ _ __ ___ ______ _ __ | |_ _ ___
4 | /// / __|/ _` / __/ __|______| '_ ` _ \ / _` | '_ \/ __|______| '_ \| | | | / __|
5 | /// \__ \ (_| \__ \__ \ | | | | | | (_| | |_) \__ \ | |_) | | |_| \__ \
6 | /// |___/\__,_|___/___/ |_| |_| |_|\__,_| .__/|___/ | .__/|_|\__,_|___/
7 | /// | | | |
8 | /// |_| |_|
9 | /// Sass Maps Plus 0.9.2
10 | /// Advanced map and list-map manipulation for all versions of Sass
11 | /// MIT License
12 | /// @author Lu Nelson
13 |
14 | /// Global sort direction: either `asc` or `desc`
15 | /// @access public
16 | /// @group map-lists/map-maps
17 | $maps-sort-dir: "asc";
18 |
19 | /// get value at nested or 'deep' key, per $keys list
20 | /// @access public
21 | /// @group maps
22 | /// @param {Map} $map - map
23 | /// @param {Arglist} $keys - nested keys
24 | /// @return {*}
25 | @function map-get-nested($map, $keys...) {
26 | @if length($map) == 0 {
27 | @return null;
28 | }
29 | @each $key in $keys {
30 | @if type-of($map) != "map" {
31 | @return $map;
32 | }
33 | $map: map-get($map, $key);
34 | }
35 | @return $map;
36 | }
37 |
38 | /// Sort a list-of-maps or map-of-maps, based on value at key(s) in maps
39 | /// @access public
40 | /// @group map-lists/map-maps
41 | /// @param {Map|List} $maps - Map of maps, or List of maps, to sort
42 | /// @param {Arglist} $keys - Chain of keys to the value that will be sorted for
43 | /// @return {Map|List}
44 | /// @require {function} map-get-nested
45 | @function maps-sort($maps, $keys...) {
46 | @if length($keys) == 0 {
47 | @return $maps;
48 | }
49 |
50 | @if length($maps) > 1 {
51 | $less: ();
52 | $equal: ();
53 | $greater: ();
54 |
55 | $map-of-maps: type-of($maps) == "map";
56 |
57 | @if $map-of-maps {
58 | $seed-map: nth(nth($maps, ceil(length($maps) / 2)), 2);
59 |
60 | $seed-value: map-get-nested($seed-map, $keys...);
61 |
62 | // TODO: add code to handle case of non-number values (warn and return $maps)
63 |
64 | @each $key, $map in $maps {
65 | $curr-value: map-get-nested($map, $keys...);
66 |
67 | @if $curr-value == $seed-value {
68 | $equal: map-merge($equal, ($key: $map));
69 | } @else if $curr-value < $seed-value {
70 | @if $maps-sort-dir == "asc" {
71 | $less: map-merge($less, ($key: $map));
72 | } @else {
73 | $greater: map-merge($greater, ($key: $map));
74 | }
75 | } @else {
76 | @if $maps-sort-dir == "asc" {
77 | $greater: map-merge($greater, ($key: $map));
78 | } @else {
79 | $less: map-merge($less, ($key: $map));
80 | }
81 | }
82 | }
83 |
84 | $less: maps-sort($less, $keys...);
85 | $greater: maps-sort($greater, $keys...);
86 |
87 | @return map-merge(map-merge($less, $equal), $greater);
88 | } @else {
89 | $seed-map: nth($maps, ceil(length($maps) / 2));
90 |
91 | $seed-value: map-get-nested($seed-map, $keys...);
92 |
93 | @each $map in $maps {
94 | $curr-value: map-get-nested($map, $keys...);
95 |
96 | @if $curr-value == $seed-value {
97 | $equal: append($equal, $map);
98 | } @else if $curr-value < $seed-value {
99 | @if $maps-sort-dir == "asc" {
100 | $less: append($less, $map);
101 | } @else {
102 | $greater: append($greater, $map);
103 | }
104 | } @else {
105 | @if $maps-sort-dir == "asc" {
106 | $greater: append($greater, $map);
107 | } @else {
108 | $less: append($less, $map);
109 | }
110 | }
111 | }
112 |
113 | $less: maps-sort($less, $keys...);
114 | $greater: maps-sort($greater, $keys...);
115 |
116 | @return join(join($less, $equal), $greater);
117 | }
118 | }
119 |
120 | @return $maps;
121 | }
122 |
--------------------------------------------------------------------------------
/src/scss/_utilities.scss:
--------------------------------------------------------------------------------
1 | @import "functions";
2 | @import "values";
3 | @import "variables";
4 |
5 | /// Function returns the value for a given breakpoint.
6 | /// @param {String} $breakpointName Breakpoint name.
7 | /// @return {Length} The breakpoint value in rems.
8 | @function get-breakpoint-value($breakpointName) {
9 | $breakpointValue: map-deep-get(
10 | $breakpointsAndArtboards,
11 | $breakpointName,
12 | "breakpoint"
13 | );
14 |
15 | @return $breakpointValue * 1rem;
16 | }
17 |
18 | /// Returns a calc() expression that represents a fluid width at a given breakpoint.
19 | /// @param {String} $breakpointName A valid breakpoint.
20 | /// @param {Number} $columnSpan The number of columns to span across.
21 | /// @return {Length} A calc() expression representing fluid width.
22 | /// @example scss
23 | /// button {
24 | /// @include media-query('sm') {
25 | /// max-width: get-fluid-size('sm', 1);
26 | /// }
27 | /// }
28 | /// @output css
29 | /// @media screen and (min-width: 20rem) {
30 | /// button {
31 | /// max-width: 25vw;
32 | /// }
33 | /// }
34 | @function get-fluid-size($breakpointName, $columnSpan) {
35 | $breakpoint: map-get($breakpointsAndArtboards, $breakpointName);
36 |
37 | @if ($breakpoint == null or type-of($breakpoint) != "map") {
38 | @error "The provided breakpoint `#{$breakpointName}` is not a valid breakpoint found in breakpoints or extraArtboards in $grid-values. Please double-check your grid configuration.";
39 | }
40 |
41 | $columnTotal: map-get($breakpoint, columns);
42 | $margin: map-get($breakpoint, margin);
43 |
44 | @if ($columnTotal == null or type-of($columnTotal) != "number") {
45 | @error "The provided breakpoint `#{$breakpointName}` needs to have a total number of columns set in $grid-values. Please double-check your grid configuration.";
46 | }
47 |
48 | @if ($columnSpan == null or type-of($columnSpan) != "number") {
49 | @error "The number of columns to span for the breakpoint `#{$breakpointName}` must be a valid number. The provided column span value `#{$columnSpan}` is not a number";
50 | }
51 |
52 | @if ($columnSpan > $columnTotal or $columnSpan <= 0) {
53 | @error "The number of columns to span for the breakpoint `#{$breakpointName}` must be greater than 0 and less than or equal to the total number of columns for this breakpoint. The provided column value `#{$columnSpan}` does not meet this criteria";
54 | }
55 |
56 | $container: 100vw;
57 | // Last breakpoint is a max-width and should be a fixed number
58 | @if is-same-breakpoint($breakpoint, $last) {
59 | $container: map-get($breakpoint, breakpoint) * 1rem;
60 | }
61 |
62 | $multiplier: round-decimal($columnSpan / $columnTotal, 4, floor);
63 |
64 | // For IE, we can't have a 0 in the $fluidWidth calc().
65 | @if ($margin == 0) {
66 | @return $container * $multiplier;
67 | }
68 |
69 | @return calc((#{$container} - #{$margin * 2}) * #{$multiplier});
70 | }
71 |
72 | /// Function gets a calculated rem value for a fixed size.
73 | /// @param {Number} $unitQuantity Fixed nondimensional units.
74 | /// @return {Length} A calculated rem value.
75 | /// @example scss
76 | /// button {
77 | /// @include media-query('sm') {
78 | /// max-width: get-fixed-size(10);
79 | /// }
80 | /// }
81 | /// @output css
82 | /// @media screen and (min-width: 20rem) {
83 | /// button {
84 | /// max-width: 5rem;
85 | /// }
86 | /// }
87 | @function get-fixed-size($unitQuantity) {
88 | // Derive the base unit from the current row height of the grid
89 | $fixedUnit: map-get($grid-values, "rowHeight");
90 |
91 | @if ($fixedUnit == null or type-of($fixedUnit) != "number") {
92 | @error "The rowHeight in $grid-values needs be a valid number. Please check your grid configuration.";
93 | }
94 |
95 | @if ($unitQuantity == null or type-of($unitQuantity) != "number") {
96 | @error "The provided fixed value `#{$unitQuantity}` to get-fixed-size() needs to be a valid number greater than 0.";
97 | }
98 |
99 | @return $unitQuantity * $fixedUnit * 1rem;
100 | }
101 |
102 | /// Utility for declaring mobile-first media queries.
103 | /// @param {String} $breakpointName The name of the breakpoint to set its width value to media query.
104 | @mixin media-query($breakpointName) {
105 | $breakpointValue: get-breakpoint-value($breakpointName);
106 | @if $breakpointValue == map-get($first, breakpoint) {
107 | @content;
108 | } @else {
109 | @media screen and (min-width: #{$breakpointValue}) {
110 | @content;
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/scss/_variables.scss:
--------------------------------------------------------------------------------
1 | @import "values";
2 |
3 | $prefix: gridish !default;
4 | @if map-get($grid-values, "prefix") and $prefix == "gridish" {
5 | $prefix: map-get($grid-values, "prefix");
6 | }
7 | $extraBreakpoints: () !default;
8 | $breakpoints: add-padding(map-get($grid-values, "breakpoints"));
9 | $first: nth(nth($breakpoints, 1), 2);
10 | $last: nth(nth($breakpoints, -1), 2);
11 | $includeFlexFallback: false !default;
12 | $rowHeight: map-get($grid-values, "rowHeight");
13 | $rows: map-get($grid-values, "rows");
14 | $extraArtboards: map-get($grid-values, "extraArtboards");
15 | $allBreakpoints: all-breakpoints(
16 | $breakpoints,
17 | $extraBreakpoints,
18 | $first,
19 | $last
20 | );
21 | $breakpointsAndArtboards: all-breakpoints(
22 | $breakpoints,
23 | $extraArtboards,
24 | $first,
25 | $last
26 | );
27 |
--------------------------------------------------------------------------------
/src/scss/gridish-grid-legacy.scss:
--------------------------------------------------------------------------------
1 | $includeFlexFallback: true;
2 | @import "core.scss";
3 |
4 | @supports (display: grid) {
5 | .#{$prefix}-grid > *,
6 | .#{$prefix}-grid > [class*="#{$prefix}-grid__col--"] {
7 | min-width: initial;
8 | max-width: initial;
9 | width: initial;
10 |
11 | &.#{$prefix}-grid {
12 | display: grid;
13 | }
14 | }
15 |
16 | .#{$prefix}-grid > [class*="#{$prefix}-grid__height--"] {
17 | height: unset;
18 | max-height: unset;
19 | min-height: initial;
20 | }
21 | }
22 |
23 | .#{$prefix}-grid > script {
24 | display: none;
25 | }
26 |
--------------------------------------------------------------------------------
/src/scss/gridish-grid.scss:
--------------------------------------------------------------------------------
1 | @import "core.scss";
2 |
--------------------------------------------------------------------------------
/src/sketch/artboard.json:
--------------------------------------------------------------------------------
1 | {
2 | "_class": "artboard",
3 | "do_objectID": "CF812E16-6AB8-4E0D-AA6C-E98BE3E292AC",
4 | "exportOptions": {
5 | "_class": "exportOptions",
6 | "exportFormats": [],
7 | "includedLayerIds": [],
8 | "layerOptions": 0,
9 | "shouldTrim": false
10 | },
11 | "frame": {
12 | "_class": "rect",
13 | "constrainProportions": false,
14 | "height": 600,
15 | "width": 320,
16 | "x": 173,
17 | "y": 103
18 | },
19 | "isFlippedHorizontal": false,
20 | "isFlippedVertical": false,
21 | "isLocked": false,
22 | "isVisible": true,
23 | "layerListExpandedType": 0,
24 | "name": "artboard1",
25 | "nameIsFixed": true,
26 | "resizingConstraint": 63,
27 | "resizingType": 0,
28 | "rotation": 0,
29 | "shouldBreakMaskChain": true,
30 | "style": {
31 | "_class": "style",
32 | "endDecorationType": 0,
33 | "miterLimit": 10,
34 | "startDecorationType": 0
35 | },
36 | "hasClickThrough": false,
37 | "layers": [],
38 | "backgroundColor": {
39 | "_class": "color",
40 | "alpha": 1,
41 | "blue": 1,
42 | "green": 1,
43 | "red": 1
44 | },
45 | "grid": {
46 | "_class": "simpleGrid",
47 | "isEnabled": true,
48 | "gridSize": 8,
49 | "thickGridTimes": 0
50 | },
51 | "hasBackgroundColor": false,
52 | "horizontalRulerData": { "_class": "rulerData", "base": 0, "guides": [] },
53 | "includeBackgroundColorInExport": true,
54 | "includeInCloudUpload": true,
55 | "layout": {
56 | "_class": "layoutGrid",
57 | "isEnabled": true,
58 | "columnWidth": 48,
59 | "drawHorizontal": false,
60 | "drawHorizontalLines": false,
61 | "drawVertical": true,
62 | "gutterHeight": 12,
63 | "gutterWidth": 32,
64 | "guttersOutside": true,
65 | "horizontalOffset": 0,
66 | "numberOfColumns": 4,
67 | "rowHeightMultiplication": 5,
68 | "totalWidth": 320
69 | },
70 | "resizesContent": false,
71 | "verticalRulerData": { "_class": "rulerData", "base": 0, "guides": [] }
72 | }
73 |
--------------------------------------------------------------------------------
/src/sketch/files/document.json:
--------------------------------------------------------------------------------
1 | {
2 | "_class": "document",
3 | "do_objectID": "0FBB6CDA-F85E-40DB-B6D3-2A9FA7AEA2D3",
4 | "assets": {
5 | "_class": "assetCollection",
6 | "colors": [],
7 | "gradients": [],
8 | "imageCollection": { "_class": "imageCollection", "images": {} },
9 | "images": []
10 | },
11 | "colorSpace": 0,
12 | "currentPageIndex": 0,
13 | "enableLayerInteraction": true,
14 | "enableSliceInteraction": true,
15 | "foreignSymbols": [],
16 | "layerStyles": { "_class": "sharedStyleContainer", "objects": [] },
17 | "layerSymbols": { "_class": "symbolContainer", "objects": [] },
18 | "layerTextStyles": { "_class": "sharedTextStyleContainer", "objects": [] },
19 | "pages": [
20 | {
21 | "_class": "MSJSONFileReference",
22 | "_ref_class": "MSImmutablePage",
23 | "_ref": "pages/BC333699-815E-4E1B-9816-9836EDA5B291"
24 | }
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/src/sketch/files/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "commit": "b8111e3393c4ca1f2399ecfdfc1e9488029ebe7b",
3 | "pagesAndArtboards": {
4 | "BC333699-815E-4E1B-9816-9836EDA5B291": {
5 | "name": "Page 1",
6 | "artboards": {
7 | "CF812E16-6AB8-4E0D-AA6C-E98BE3E292AC": { "name": "artboard1" }
8 | }
9 | }
10 | },
11 | "version": 97,
12 | "fonts": [],
13 | "compatibilityVersion": 93,
14 | "app": "com.bohemiancoding.sketch3",
15 | "autosaved": 0,
16 | "variant": "NONAPPSTORE",
17 | "created": {
18 | "commit": "b8111e3393c4ca1f2399ecfdfc1e9488029ebe7b",
19 | "appVersion": "48.2",
20 | "build": 47327,
21 | "app": "com.bohemiancoding.sketch3",
22 | "compatibilityVersion": 93,
23 | "version": 97,
24 | "variant": "NONAPPSTORE"
25 | },
26 | "saveHistory": ["NONAPPSTORE.47327"],
27 | "appVersion": "48.2",
28 | "build": 47327
29 | }
30 |
--------------------------------------------------------------------------------
/src/sketch/files/pages/BC333699-815E-4E1B-9816-9836EDA5B291.json:
--------------------------------------------------------------------------------
1 | {
2 | "_class": "page",
3 | "do_objectID": "BC333699-815E-4E1B-9816-9836EDA5B291",
4 | "exportOptions": {
5 | "_class": "exportOptions",
6 | "exportFormats": [],
7 | "includedLayerIds": [],
8 | "layerOptions": 0,
9 | "shouldTrim": false
10 | },
11 | "frame": {
12 | "_class": "rect",
13 | "constrainProportions": false,
14 | "height": 300,
15 | "width": 300,
16 | "x": 0,
17 | "y": 0
18 | },
19 | "isFlippedHorizontal": false,
20 | "isFlippedVertical": false,
21 | "isLocked": false,
22 | "isVisible": true,
23 | "layerListExpandedType": 0,
24 | "name": "Page 1",
25 | "nameIsFixed": false,
26 | "resizingConstraint": 63,
27 | "resizingType": 0,
28 | "rotation": 0,
29 | "shouldBreakMaskChain": false,
30 | "style": {
31 | "_class": "style",
32 | "endDecorationType": 0,
33 | "miterLimit": 10,
34 | "startDecorationType": 0
35 | },
36 | "hasClickThrough": true,
37 | "horizontalRulerData": { "_class": "rulerData", "base": 0, "guides": [] },
38 | "includeInCloudUpload": true,
39 | "verticalRulerData": { "_class": "rulerData", "base": 0, "guides": [] }
40 | }
41 |
--------------------------------------------------------------------------------
/src/sketch/files/previews/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/css-gridish/c5f16a541df485fa833f8f50299bd6a3f290a142/src/sketch/files/previews/preview.png
--------------------------------------------------------------------------------
/src/sketch/files/user.json:
--------------------------------------------------------------------------------
1 | {
2 | "BC333699-815E-4E1B-9816-9836EDA5B291": {
3 | "scrollOrigin": "{23, 32}",
4 | "zoomValue": 1
5 | },
6 | "0FBB6CDA-F85E-40DB-B6D3-2A9FA7AEA2D3": { "pageListHeight": -1 }
7 | }
8 |
--------------------------------------------------------------------------------