乐趣区

重温 Flex 布局

介绍
这是关于 Flex 布局的实践,原想还水一点字数来介绍 Flex 相关属性,想想还是算了,阮一峰大佬的两篇文章推上:

Flex 布局教程:语法篇
Flex 布局教程:实例篇

如何用 CSS 来增进对 Flex 的理解:

CSS 搞事技巧:checkbox+label+selector
CSS 搞事技巧:hover+active

常规布局
1. 两栏布局
左侧定宽,右侧自适应:

源码
<Layout-Layout
:background-color=”bgColor”
class=”flex-layout”
>
<div class=”flex__item”>left</div>
<div class=”flex__item”>right</div>
</Layout-Layout>
.flex-layout
display flex
.flex__item
&:nth-child(1)
background-color #c04851 // 玉红
flex 0 0 200px
&:nth-child(2)
background-color #440e25 // 古铜紫
flex 1 1 auto
原因解释:
flex 是一个简写属性,用来设置 flex-grow、flex-shrink、flex-basis。一般来说让元素等高需要额外设置,而 flex 容器的存在一个默认属性值:align-items:stretch,它会帮助你,当然也会给你带来糟糕的体验。
2. 三栏布局
圣杯布局与双飞翼布局都是三栏布局,稍微介绍一下:圣杯布局关键是父元素设置 padding,接着子元素通过 margin 负值以及定位;双飞翼布局关键是中间一栏多了子元素并设置 margin,然后侧边栏使用 margin 负值。而通过 flex 实现则简单多了:

源码
<Layout-Layout
:background-color=”bgColor”
class=”holy-grail”
>
<div class=”flex__content”>content</div>
<div class=”flex__nav”>nav</div>
<div class=”flex__side”>side</div>
</Layout-Layout>
.holy-grail
display flex
.flex__content
flex 1 1 auto
background-color #009999
.flex__nav, .flex__side
flex 0 0 120px
.flex__nav
order -1
background-color #1D7373
.flex__side
background-color #33CCCC
原因解释:
中间一栏为核心,所以需要优先渲染,DOM 结构也就放在了前面,主要是使用 order 属性将 nav 放置到前方。
常见布局
除了整体结构用到这些布局以外,对于一些组件也常常需要一些简单的布局。
1. 导航栏
模仿示例:

实现效果图:

源码
<header class=”header”>
<div class=”header__avatar”></div>
<div class=”header__title”>Title</div>
<div class=”header__more”></div>
</header>
.header
height 100px
width 100%
background-color #f9f1db // 蚌肉白
display flex
align-items center
> *
margin 0 10px
&__avatar, &__more
flex 0 0 80px
height 80px
border-radius 50%
&__avatar
background-color #FFAC40
&__title
color #FF9000
&__more
margin-left auto
background-color #A65E00
原因解释:
此处主要是利用了 margin-auto 来占据剩余的空间,就与我们使用 margin: 0 auto 来获取水平居中一样。
2. 输入框
模仿示例:

实现效果图:

源码
<Layout-Layout
align-center
justify-center
:background-color=”bgColor”
>
<div class=”input-group”>
<span class=”title” @click=”message = !message” v-if=”message”>Message</span>
<input type=”text” class=”input-text”>
<span class=”icon” @click=”icon = !icon” v-if=”icon”></span>
</div>
</Layout-Layout>
.input-group
flex 0 0 75%
height 40px
border 2px solid red
border-radius 4px
display flex
align-items center
> *
box-sizing border-box
.input-text
font-size 20px
padding-left 10px
height 100%
flex 1
outline none
border none
.icon
flex 0 0 24px
height 24px
border-radius 50%
background-color #648e93 // 晚波蓝
原因解释:
这也是一个常规的三栏布局,关键是 .input-text 的 flex: 1 属性可以占据剩余空间,当其余配件不存在时也可以相应的扩张。
3. 卡片
实现效果图:

源码
<Layout-Layout
:background-color=”bgColor”
class=”flex-card”
>
<header class=”header”></header>
<article class=”article”>
<div class=”article__item”>1</div>
<div class=”article__item”>2</div>
<div class=”article__item”>3</div>
<div class=”article__item”>4</div>
<div class=”article__item”>5</div>
<div class=”article__item”>6</div>
</article>
<footer class=”footer”></footer>
</Layout-Layout>
.flex-card
display flex
flex-flow column nowrap
.header
flex-basis 80px
background-color #4E51D8
.footer
flex-basis 50px
background-color #00B060
.article
flex auto
background-color #FF9000
display flex
flex-flow row wrap
align-content center
justify-content space-around
&__item
width 28%
height 50px
box-shadow 0 2px 4px rgba(255, 255, 255, .4), 3px 0 5px rgba(0, 0, 0, .6)
原因解释:
将主轴修改为垂直方向,header 和 footer 因为 article 的 flex:auto 属性被分别顶至上方和下方,可以避免 absolute 的滥用。在中间使用 align-content 区别于 align-items,可以将多行元素视为一个整体。
4. 瀑布流
实体效果:
在编译时会赋予 CSS 颜色,所以直接刷新页面是不可行的,只有重新保存代码进行编译可以变更颜色。

源码
<Layout-Layout
:background-color=”bgColor”
class=”flex-flow”
>
<div
class=”flow-column”
v-for=”m in 5″
:key=”m”
>
<div
class=”flow-item”
v-for=”n in 8″
:key=”n”
></div>
</div>
</Layout-Layout>
$flow-columns = 5; // flow 的列数
$flow-items = 8; // flow 每列的个数

// 函数
randomColor(min, max) {
return floor(math(0, ‘random’) * (max – min + 1) + min);
}

randomPx(min, max) {
return floor(math(0, ‘random’) * (max – min + 1) + min) px;
}

.flex-flow {
display: flex;
justify-content: space-between;
overflow: hidden;

.flow-column {
display: flex;
flex-direction: column;
flex: 0 0 18.6%;

.flow-item {
width: 100%;
margin: .1rem 0;
}
}
}

for column in (1 .. $flow-columns) {
.flow-column:nth-child({column}) {

for item in (1 .. $flow-items) {
.flow-item:nth-child({item}) {
flex: 0 0 randomPx(30, 100);
background-color: rgb(
randomColor(0, 255),
randomColor(0, 255),
randomColor(0, 255)
);
}
}
}
}
原因解释:
flex 实现瀑布流还是比较简单的。友情提示:当使用 stylus 时还是加上标点符号吧,找编译错误花了我近二十分钟。
最后
合并多个 commit
在 push 前需要合并 commit:
git log –oneline
git rebase -i xxxxxxx
git log –oneline
git status
git push
初步地把 CSS 稍微过了一遍,下一步继续完善那个简陋的 简历 了…
参考资料

VSCode 的友情提示
Vuetify

退出移动版