css横向排列_从零开始の CSS 学习笔记——布局(上)

6bc53709c48d61be3ce37ba33465a73d.png

主要内容:float布局、flex布局

布局是什么

把页面分成一块一块,按左中右、上中下等排列

布局分类


两种

  • 固定宽度布局,一般宽度为 960/1000/1024px (淘宝pc)
  • 不固定宽度布局,主要靠文档流的原理来布局(常用在移动端、响应式,会跟随设备宽度变化)

还记得吗

  • 文档流本来就是自适应的,不需要加额外的样式

第三种布局

  • 响应式布局
    • 意思就是PC上固定宽度,手机上不固定宽度
    • 也就是一种混合布局

布局的两种思路
从大到小

  • 先定下大局
  • 然后完善每个部分的小布局

从小到大

  • 先完成小布局
  • 然后组合成大布局

两种均可

  • 新人推荐用第二种,因为小的简单
  • 老手一般用第一种,因为熟练有大局观


布局需要用到哪些属性
不多哔哔,直接给你所有套路
以前经常说 DIV+CSS 布局,但是现在已经无意于用 DIV 了,就说用 CSS 布局

  • main、header、footer、nav、aside … 这些标签的出现,已经可以代替 div 了

需要兼容 IE9 吗

  • 不用,只做手机页面(闲鱼),阿里巴巴在顺应手机时代
  • 很老的手机产品要兼容吗?兼容最新浏览器吗?

e0589aa32bfc676e7a63d5914c6175b4.png


Float 布局
float 主要是针对 IE 的,而现在公司基本不需要兼容 IE6789。 步骤

  1. 子元素上加 float: left width
  2. 在父元素上加 .clearfix(清除浮动的影响)
 <!-- header中没有文档流元素,子元素都浮动了(脱离文档流) ,所以header的高度为0 -->
<!-- 添加 clearfix 后,可以清除浮动的影响 -->
<header class="clearfix">    
  <div class="logo">XDML</div>
    <nav>导航</nav>
</header>

<style>
    .logo{float: left;...}   /* 脱离文档流 */
    nav{float: left;...}
</style>
.clearfix:after{    
  content: '';
  display: block;
  clear: both;
}
/* 请背过 clearfix 的写法 */

经验

  • 有经验者会留一些空间或者最后一个不设 width (或者可以给个 max-width: xxxpx;
  • 不需要做响应式,因为手机上没有IE,而这个布局是专门为 IE 准备的
  • IE6/7 存在双倍 margin bug(给浮动元素设置 margin: 10px 在 IE6/7 中实际距离会变成 margin: 20px 的效果)
    • 解决办法有两个
.logo{
  float: left;
  margin-top: 10px;  /* 其他浏览器 只能识别这句,无法识别下面属性 */
  _margin-top: 5px;  /* IE6/7在属性前加 下划线 或 星号 都能识别 */
}
      • 二是神来一笔,再加一个 display: inline-block
.logo{
  float: left;
  margin-top: 10px; 
  display: inline-block;  /* 微软说:IE6/7遇到margin乘2的bug,就添加这句 */
}
        • 为什么可以这样?你问我,我问谁…

实践


不同布局

  • 用 float 做两栏布局(如顶部条)
  • 用 float 做三栏布局(如内容区)
  • 用 float 做四栏布局(如导航)
  • 用 float 做平均布局(如产品列表展示区)—— 负margin
  • 曾经淘宝的前端发明了双飞翼布局,现在可以不用学了,已过时代码

经验

  • 加上头尾,即可满足所有PC页面需求
  • 手机页面傻子才用float
  • float要程序员自己计算宽度,不灵活
  • float用来应付IE足以

技术总结

JSbin 演示,总结如下

outline

现象描述:计算宽度时,内部3个元素的宽度和=300,外层容器=300,但是还会把最后一个元素挤下去,说明子元素的宽度超出容器的宽度。
  • 原因可能是,虽然设定容器宽度为 300,但是容器添加了边框 border : 1像素,所以容器的内容区域的宽度实际只有 298 px。(仅限 border-box 情况)
  • 解决:
把容器的边框删了
改用 outline: 1px solid red; outline 是在外侧的,不占内部区域,但是outline 样式上会有点奇怪
改用 背景颜色 标识区域

居中

/* margin: 0 auto;  下面两句的写法更好,这句还覆盖了margin上下的距离,css原则是不要写多余的 */    
margin-left: auto;
margin-right: auto;
只有 块级元素,才能使用 margin … auto,实现居中。


float实现平均布局


添加一个 父元素 x ,进行 负margin 操作(这个词基本都是高手才懂)
注意:添加 父元素后,clearfix 的位置也需要相应移动到,浮动元素的直属父级上

<div class="imageList">
  <div class="x clearfix">
    <div class="image"></div>
    <div class="image"></div>
    <div class="image"></div>
    <div class="image"></div>
    <div class="image"></div>
    <div class="image"></div>
    <!--<div class="image"></div>-->
    <!--<div class="image"></div>-->
  </div>
</div>
<style>
  .imageList {
    outline: 1px solid green;
    width: 800px;
    margin-left: auto;
    margin-right: auto;
    margin-top: 10px;
  }
  .imageList > .x > .image {
    width: 191px;
    height: 191px;
    background-color: #555;
    border: 1px solid red;
    float: left;
    margin-bottom: 10px;
    margin-right: 12px;
  }
  .imageList > .x {
    margin-right: -12px;
  }
</style>

6abc41b12c291ce7f71ecfd0316f040f.png


缩写

html、css (√)
navigator ---> nav (√)
不能缩写未经约定、达成统一的单词
content —> cnt (x) container 也可以缩写成 cnt 容易误会,所以不要用



Flex 布局

  • 教程(来自 CSS Tricks)
  • 把教程过一遍,然后忘掉
  • 完成 Flex青蛙游戏
  • 开始用flex!

容器 container 有哪些属性

  • container :表示容器,一般用于做父元素
  • items :表示容器里面的、直接的子元素,就称为 items(项)

6d38b621ac237fdcc7647cf860342f77.png

以下都是 container 的样式

让一个元素变成 flex 容器
只有下面两种写法:

 ..container{
  display: flex;     /* 或 display: inline-flex; */
}


改变 items 流动方向(主轴)
默认,所有项都会挤在主轴,主轴占满会平均压缩每项宽度,以保证在主轴存放下所有项

1487ba9360002a9ab21e1b766833269a.png
 .container{
  display: flex;
  border: 1px solid red;
  flex-direction: row;  /* 【默认值】横向(从左到右) */
  flex-direction: column;  /* 纵向(从上到下) */
  flex-direction: row-reverse; /* 横向反向(从右到左) */
  flex-direction: column-reverse; /* 纵向反向(从上到下) */
}


改变折行

b791933800e747b45f5f76912b0181ae.png
.container{
  display: flex;
  border: 1px solid red;
  flex-direction: row;  /* 默认横向 */
  flex-wrap: wrap-reverse;  /* 反向折行, 效果如下图,基本没用 */
}

122c6b7032276ddf98ba0a69c8a0a7db.png
flex-directionflex-wrap两个属性经常会一起使用,所以有缩写属性 flex-flow。这个缩写属性接受两个属性的值,两个值中间以空格隔开。
举个例子,你可以用 flex-flow: row wrap去设置行并自动换行。


主轴对齐方式

默认主轴是 横轴
除非你改变了 flex-direction 方向

d953edf7545b1dc5d5422c80d82e0e02.png

c12167af8d4a5f904858d898177988d5.png
.container {
  justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}
  • space-around: 每项左右两边的空间一样
  • space-evenly:每项间距一样
  • space-between:把空间放到中间,元素分布两边


次轴对齐

默认次轴是 纵轴
.container{
  align-items: stretch [默认值] | flex-start | flex-end | center | baseline(不需要) 
}

805eb5578868d1ea0a997ba2ff4a6830.png
  • stretch【默认值】
    • 默认所有 items 的高度 与 高度最高的 item 保持一致
    • 如下图,3个 item 都与 2 号 item 一样高

01c8912961858d9e02ae38387bad06ba.png
  • flex-start

5de41f883c5d3974ded540411d0084ca.png
  • flex-end

77cbd4321cc25ceebd135cf52d22d464.png
  • center

97a07bbc7b941d83b5ac8d9d5d8aad82.png

多行分布
很少用到

  • 默认平均分 : align-content: stretch (如图)

bc0d35221a534a17106424bb271a1e93.png
  .container{
  display: flex;
  border: 1px solid red;
  flex-wrap: wrap;
  height:400px;
  align-content: flex-start;   /* 全部集中到顶部 */
  align-content: flex-end;   /* 全部集中到底部 */
  align-content: center;   /* 全部集中到中间 */
  align-content: space-between;
  align-content: space-around;
}

f9c58f8b72d316e68cc768002a0e955e.png



flex item 有哪些属性

以下都是 item 的属性


item 上加 order

  • 默认 order 为 0
  • 指定 order 后,item 会按照 order 顺序从小到大排列(可以指定为负数)

41c87deb74a3dedd8b0ef4027973c2f8.png
 <div class="container">
  <div class="item">1</div>
  <div class="item">2</div>  
  <div class="item">3</div>
  <div class="item">4</div>
</div>

<style>
  .container{
    display: flex;
    border: 1px solid red;
  }
  .item{
    width:50px;
    height:50px;
    border: 1px solid green;
  }
  .item:first-child{ order: 100; }    /* 最后 */
  .item:nth-child(2){ order: 2; }           
  .item:nth-child(3){ order: 3; }
  .item:last-child{ order: 1; }    /* 最前 */
</style

016704fabbd4fe3d35d96755eedfb9bd.png


item 上加 flex-grow
用于分配多余的空间(控制变胖)

  • flex-grow: 默认为 0. 就是 item 宽度由内容撑开,没内容的话宽度就是0,不会占用多余的空间
  • 给 item 设置 flex-grow 值为 n (>0),就是将分配多余空间给当前 item 占 n 份。
    • 如果一共有3个item,那就平均分配多余空间,每个 item 占 n/3.

2bd8144dc10b4a5c483618a3cef4ee44.png
  • 当我们不给 item 设置宽度时,item 的宽度是能有多窄有多窄(宽度由内容撑开)

181a6fb6d4ddadcfc4c675b72cceb0af.png
  • 实现宽度能有多宽有多宽,就给 item 添加 flex-grow
.item{
  flex-grow: 1;    /* 每一个 item 平均分配宽度,来占满多余的空间(不是占满整行空间) */
}

243b1adcac7f49cacedbdaca3d26b1f0.png
  • 需求:从多余的空间中,给2,3 的宽度占 2 份; 给 1,4 占 1 份 空间
.container{
  display: flex;
  border: 1px solid red;
}
.item{
  height:50px;
  border: 1px solid green;
}
.item:first-child{ flex-grow: 1; }
.item:nth-child(2){ flex-grow: 2; }
.item:nth-child(3){ flex-grow: 2; }
.item:last-child{ flex-grow: 1; }

0fa736790e0bf45795e93aa90fbc80f5.png

经验

  • 当 3 栏布局,如下
    • 只给【导航】设置 flex-grow: 1(实现导航宽度的响应式),logo、头像固定宽度
<div class="container">
  <div class="item">logo</div>
  <div class="item">导航</div>  
  <div class="item">头像</div>
</div>

<style>
  .container{
    display: flex;
    border: 1px solid red;
  }
  .item{
    height:50px;
    border: 1px solid green;
  }
  .item:nth-child(2){   
    flex-grow: 1; 
  }
</style>

31a7ff0a1c163ba7c591cd029f19a273.png


flex-shrink 控制如何变瘦

当界面不断变窄,无法存放每项的给定宽度时,每项都需要变窄,flex-shrink 就控制谁瘦的多,谁瘦的少
默认是1(所有item平均收缩,要缩一起缩)
一般写 flex-shrink: 0; 防止变瘦(被设置为 0 的这一项,就算空间不够时,也不会收缩。要缩别找我)
.item{
  width: 150px;  /* 合计宽度最小450px */
  height:50px;
  border: 1px solid green;
  flex-grow: 1;  /* 每项会均分多余空间 */
}
.item:first-child{
  flex-shrink: 1;
}
.item:nth-child(2){ 
  flex-shrink: 50;   /* 2 的收缩比例较大 */
}
.item:last-child{
  flex-shrink: 1;
}
  • 当宽度缩小达到450px以内,每项宽度不足,此时每项会开始收缩, flex-shrink 值越大,则收缩的越大,flex-shrink 值越小,越不会受到收缩的影响
    • 如下图,宽度收缩450px以内,【导航】最先开始发生了较大的收缩,因为设定了较大的 flex-shrink 值
    • 【logo】和【头像】版块,基本不收缩

611ccd3e827d1862b3f7c98be7e67eba.png


flex-basis 控制基准宽度
用法:

  • 默认是 auto(与 item 的 width 值保持一致)
  • 指定宽度:flex-basis: 100px; 相当于指定了 width 值


这个属性也比较迷:不是很重要的属性

  • 可以直接用 width 来代替这个属性


缩写成 flex

flex 相当于 flex-grow flex-shrink flex-basis
习惯上我一般不写缩写,容易记错位置
  • flex 只有以下 4 种形式的写法

490755abfa7f6226151d06bfdd8becaf.png
.item:first-child{
  flex: 1 1 100px;    /* grow-1,shrink-1,宽100px */
}
.item:nth-child(2){
  flex: 1 100 100px;    /* grow-1,shrink-100,宽100px */
}
.item:last-child{
  flex: 1 1 100px;    /* grow-1,shrink-1,宽100px */
}

作者:SamRock
链接:https://juejin.im/post/6856796010077749261
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 
  • 上述,3个item,宽度为100px
    • grow撑开时每个item平均占满所有多余空间
    • 宽度不足时,2 号主要进行收缩


align-self 定制 align-items
用的很少

默认在垂直方向上,都是顶端对齐的
align-self 可以让某一个 item,在垂直方向上,特例独行的展示(指定一个特别的对齐方式)

44a2e577d9b8901896b5be25b2424a6c.png

实现:单独设置,最后一个 item 底部对齐

0cff4331b94998b59555f58d2bcef39a.png


重点

记住这些代码 display: flex 开启flex布局 flex-direction: row / column 主轴是横向还是纵向 flex-wrap: wrap 空间不足时是否换行 just-content: center / space-between 主轴方向上的对齐方式:居中/分开 align-items: center 次轴方向上的对齐方式:居中,顶,底
工作中基本只用这些


实践

不同布局

  • 用 flex 做两栏布局
  • 用 flex 做三栏布局
  • 用 flex 做四栏布局
  • 用 flex 做平均布局 —— 负 margin
  • 用 flex 组合使用,做更复杂的布局
  • JSBin 代码

经验

  • 永远不要把 width 和 height 写死,除非特殊说明
    • PC端通常可以写死。移动端不能写死,需要适配各种尺寸:平板/手机…
  • 用 min-width / max-width / min-height / max-height
  • flex 可以基本满足所有需求
  • flex 和 margin-xxx : auto 配合有意外的效果——例:左右布局


什么叫写死


写死

  • width:100px

不写死

  • width: 50%
  • max-width: 100px
  • width: 30vw (屏幕宽度的百分之30)
  • min-width: 80%
  • 特点:不使用 px,或者加 min max 前缀
css 最忌讳把宽高写死


技术总结


左右布局

  • 表示两栏布局-贴左、贴右:可通过以下两句中的任意一句来实现
  • margin-xxx: auto 更灵活
<style>
  .header {
    display: flex;
    border:1px solid black;
    /*justify-content: space-between; ---------------二者任选其一----------------------*/
  }
  ul {
    /* margin-left: auto; -------------------------二者任选其一【推荐】------------------*/
    display: flex;
    border: 1px solid green;
  }
  ul > li {
    border: 1px solid red;
  }
</style>

<header class="header">
  <div class="logo">
    <img alt="" src="./logo.png">
  </div>
  <ul>
    <li>首页</li>
    <li>课程</li>
    <li>优惠</li>
    <li>关于</li>
  </ul>
</header>

产品展示格子布局
失败方案

 <div class="imageList">
  <div class="image"></div>
  <div class="image"></div>
  <div class="image"></div>
  <div class="image"></div>
  <div class="image"></div>
  <div class="image"></div>
  <div class="image"></div>
</div>
.imageList{
  border: 1px solid red;
  width: 800px;
  margin-right: auto;
  margin-left: auto;
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;  /* 会导致产品不足数的行 --> 错位 */
}
.image{
  width: 191px;
  height: 191px;
  background-color: #ccc;
  margin-bottom: 10px;
  border: 1px solid green;
}

72a919619cb0e0b7fa4eb2f0ab11fe83.png

负margin方案

 <div class="imageList">
  <!-- 可以命名为 inner 或者 wrapper -->
  <div class="x">
    <div class="image"></div>
    <div class="image"></div>
    <div class="image"></div>
    <div class="image"></div>
    <div class="image"></div>
    <div class="image"></div>
    <div class="image"></div>
  </div>
</div>
.imageList {
  outline: 1px solid red;   /* 注意:边框去掉或者放在外面,否则占据宽度 */
  width: 800px;
  margin-right: auto;
  margin-left: auto;
  margin-top: 10px;
}
.imageList > .x {
  display: flex;
  flex-wrap: wrap;
  margin-right: -12px;    /* 负margin */
}
.image {
  width: 191px;
  height: 191px;
  background-color: #ccc;
  margin-bottom: 10px;
  border: 1px solid green;
  margin-right: 12px;  /* 每个的间距 */
}

2a67c739fdb6bb8886e503bbad54dd5c.png

看完2件事:

如果你觉得这篇内容对你挺有启发,我想邀请你帮我个小忙

点赞,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓-_-)
作者:SamRock
链接:https://juejin.im/post/6856796010077749261
来源:掘金

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值