创建一个方便设计的自定义栅格布局
让我们看看如何使用css创建栅格覆盖(grid overlay),这是响应式的,且很容易用户自定义,使用的是css变量(和"css custom properties"相对应)。
grid overlay是开发者的工具,而不是对于用户而言的。所以我们不需要过多的担忧浏览器兼容问题。可以使用postCSS插件cssnext来改变css变量属性,让其兼容旧版浏览器器。
##序言:
当我适应flex布局的时候,我的小伙伴看不懂,所有我创建了可以切换的grid overlay来帮助他们视觉化解说我的布局,而不需要说抽象的具体宽高或者padding值。
##术语
作为前端,尽量使用前端熟悉的术语:
列column: 页面的垂直分布
沟gutter: 列之间的空间
偏移offset:视口(viewport)之间的空间
基准线baseline:作用于文本的垂直rhythm
##创建grid
1)盒子box
我们使用元素上的pseudo元素来呈现grid。我们想要在一个流式布局的容器里面限制另一个容器的大小,那么可设置里面容器的大小为 100%-(2*offset),且设置一个最大宽度,这样的grid overlay将不会比外面流式布局的容器宽
css:
/* Settings */ :root { --offset: 2rem; --max_width: 72rem; --color: hsla(204, 80%, 72%, 0.25); } /* Styling */ html { position: relative; } html::before { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin-right: auto; margin-left: auto; width: calc(100% - (2 * var(--offset))); max-width: var(--max_width); min-height: 100vh; content: ''; background-color: var(--color); z-index: 1000; pointer-events: none; } /* Codepen styling */ body { height: 400vh; }
效果:
2)列columns
如果你发现你页面的循环模式是“列+沟(column+glutter)”对的形式出现,那么我们可以使用重复的线性gradients(repeating linear gradients)作为背景图片(background-image)
我们可设置背景图片的大小是100%+glutter,让单个循环的模式是100%/columns宽,且设置具体的column为 (100%/columns)-gutter宽度
css:
/* Settings */ :root { --offset: 2rem; --max_width: 72rem; --columns: 6; --gutter: 1rem; --color: hsla(204, 80%, 72%, 0.25); } /* Helper variables */ :root { --repeating-width: calc(100% / var(--columns)); --column-width: calc((100% / var(--columns)) - var(--gutter)); --background-width: calc(100% + var(--gutter)); --background-columns: repeating-linear-gradient( to right, var(--color), var(--color) var(--column-width), transparent var(--column-width), transparent var(--repeating-width) ); } /* Styling */ html { position: relative; } html::before { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin-right: auto; margin-left: auto; width: calc(100% - (2 * var(--offset))); max-width: var(--max_width); min-height: 100vh; content: ''; background-image: var(--background-columns); background-size: var(--background-width) 100%; z-index: 1000; pointer-events: none; } /* Codepen styling */ body { height: 400vh; }
效果;
3)基准线baseline
可以很方便的向上或者向下增加水平线,下面的例子中通过廖正background-position来调整水平线的位置:
/* Settings */ :root { --offset: 2rem; --max_width: 72rem; --columns: 6; --gutter: 1rem; --baseline: 3rem; --baseline-offset: 2rem; --color: hsla(204, 80%, 72%, 0.25); } /* Helper variables */ :root { --repeating-width: calc(100% / var(--columns)); --column-width: calc((100% / var(--columns)) - var(--gutter)); --background-width: calc(100% + var(--gutter)); --background-columns: repeating-linear-gradient( to right, var(--color), var(--color) var(--column-width), transparent var(--column-width), transparent var(--repeating-width) ); --background-baseline: repeating-linear-gradient( to bottom, var(--color), var(--color) 1px, transparent 1px, transparent var(--baseline) ); } /* Styling */ html { position: relative; } html::before { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin-right: auto; margin-left: auto; width: calc(100% - (2 * var(--offset))); max-width: var(--max_width); min-height: 100vh; content: ''; background-image: var(--background-columns), var(--background-baseline); background-size: var(--background-width) 100%; background-position: 0 var(--baseline-offset); z-index: 1000; pointer-events: none; } /* Codepen styling */ body { height: 400vh; }
效果:
4)媒体查询media Queries
我们回顾之前可以看见我们从来木有给列,沟等等设置具体的值。
/* Settings */ :root { --offset: 1.5rem; --max_width: 72rem; --columns: 6; --gutter: .5rem; --baseline: 3rem; --baseline-shift: 2rem; --color: hsla(204, 80%, 72%, 0.25); } @media (min-width: 35em) { :root { --offset: 2rem; --gutter: .75rem; --color: hsla(286, 51%, 44%, 0.25); } } @media (min-width: 48em) { :root { --offset: 3rem; --columns: 12; --gutter: 1rem; --color: hsla(204, 80%, 72%, 0.25); } } @media (min-width: 70em) { :root { --offset: 4rem; --color: hsla(286, 51%, 44%, 0.25); } }
我们可使用--max_width来针对每个媒体查询。
##帮助文本
就是针对不同的媒体大小设置标志,来指代不同范围的媒体大小
例如,iphone在samll标志范围内,ipad在big标志范围内等等
可以根据用户自己设置标志范围和名字:
/* Settings */ :root { --offset: 1.5rem; --max_width: 72rem; --columns: 6; --gutter: .5rem; --baseline: 3rem; --baseline-shift: 2rem; --color: hsla(204, 80%, 72%, 0.25); --media-query: 'base'; } @media (min-width: 35em) { :root { --offset: 2rem; --gutter: .75rem; --color: hsla(286, 51%, 44%, 0.25); --media-query: 'small'; } } @media (min-width: 48em) { :root { --offset: 3rem; --columns: 12; --gutter: 1rem; --color: hsla(204, 80%, 72%, 0.25); --media-query: 'medium'; } } @media (min-width: 70em) { :root { --offset: 4rem; --color: hsla(286, 51%, 44%, 0.25); --media-query: 'large'; } } /* Helper variables */ :root { --repeating-width: calc(100% / var(--columns)); --column-width: calc((100% / var(--columns)) - var(--gutter)); --background-width: calc(100% + var(--gutter)); --background-columns: repeating-linear-gradient( to right, var(--color), var(--color) var(--column-width), transparent var(--column-width), transparent var(--repeating-width) ); --background-baseline: repeating-linear-gradient( to bottom, var(--color), var(--color) 1px, transparent 1px, transparent var(--baseline) ); } html { position: relative; } html::before { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin-right: auto; margin-left: auto; width: calc(100% - (2 * var(--offset))); max-width: var(--max_width); min-height: 100vh; content: ''; background-image: var(--background-columns), var(--background-baseline); background-size: var(--background-width) 100%; background-position: 0 var(--baseline-shift); z-index: 1000; pointer-events: none; } html::after { content: var(--media-query); position: fixed; top: 1rem; left: 1rem; font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; color: var(--color); } /* Codepen styling */ body { height: 400vh; }
##实战:栅格系统
如何做到上面一样的栅格系统呢
简单啊:
/* Settings */ :root { --offset: 1.5rem; --max_width: 72rem; --columns: 6; --gutter: .5rem; --baseline: 1rem; --baseline-shift: calc(var(--baseline) / 2); --line-thickness: 1px; --color: hsla(204, 80%, 72%, 0.25); --media-query: 'base'; } @media (min-width: 35em) { :root { --offset: 2rem; --gutter: .75rem; --baseline: 1.5rem; --color: hsla(286, 51%, 44%, 0.25); --media-query: 'small'; } } @media (min-width: 48em) { :root { --offset: 3rem; --columns: 12; --gutter: 1rem; --baseline: 2rem; --color: hsla(204, 80%, 72%, 0.25); --media-query: 'medium'; } } @media (min-width: 70em) { :root { --offset: 4rem; --baseline: 3rem; --color: hsla(286, 51%, 44%, 0.25); --media-query: 'large'; } } /* Helper variables */ :root { --repeating-width: calc(100% / var(--columns)); --column-width: calc((100% / var(--columns)) - var(--gutter)); --background-width: calc(100% + var(--gutter)); --background-columns: repeating-linear-gradient( to right, var(--color), var(--color) var(--line-thickness), transparent var(--line-thickness), transparent calc(var(--column-width) - var(--line-thickness)), var(--color) calc(var(--column-width) - var(--line-thickness)), var(--color) var(--column-width), transparent var(--column-width), transparent var(--repeating-width) ); --background-baseline: repeating-linear-gradient( to bottom, var(--color), var(--color) 1px, transparent 1px, transparent var(--baseline) ); } html { position: relative; } html::before { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin-right: auto; margin-left: auto; width: calc(100% - (2 * var(--offset))); max-width: var(--max_width); min-height: 100vh; content: ''; background-image: var(--background-columns), var(--background-baseline); background-size: var(--background-width) 100%; background-position: 0 var(--baseline-shift); z-index: 1000; pointer-events: none; } html::after { content: var(--media-query); position: fixed; top: 1rem; left: 1rem; font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; color: var(--color); } /* Codepen styling */ body { height: 400vh; }