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

a71cada34a06811d91859ddbda43e89f.png

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

布局是什么

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

布局分类

两种

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

还记得吗

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

第三种布局

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

布局的两种思路

从大到小

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

从小到大

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

两种均可

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

布局需要用到哪些属性

不多哔哔,直接给你所有套路

以前经常说 DIV+CSS 布局,但是现在已经无意于用 DIV 了,就说用 CSS 布局

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

需要兼容 IE9 吗

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

45ea8d4da185fcf4d1a510ebb36d7e52.png

Float 布局

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

步骤

  1. 子元素上加 float: leftwidth
  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 的效果)
    • 解决办法有两个
      • 一是将错就错,针对 IE6/7 把 margin 减半
.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>

df72569cfba3cb835adc3c9f42cc0650.png

缩写

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

Flex 布局

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

容器 container 有哪些属性

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

07610169f6f38e0b92509ca8a8072f1a.png
以下都是 container 的样式

让一个元素变成 flex 容器

只有下面两种写法:

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

改变 items 流动方向(主轴)

默认,所有项都会挤在主轴,主轴占满会平均压缩每项宽度,以保证在主轴存放下所有项

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

改变折行

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

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

主轴对齐方式

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

020ac1caa817943f5decf1b13ef4c948.png

cf06845ec423e067b06b487d5d9418f5.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(不需要) 
 }

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

29a3bd5929df1481f29b7dccf950c4b5.png
  • flex-start

b51ad053935b750499979929ee289ca9.png
  • flex-end

ffea933e6986d77ddc18593f674daced.png
  • center

aad8a9d0c6fed2fadbb8ad96e110eeb2.png

多行分布

很少用到
  • 默认平均分 : align-content: stretch (如图)

b4c26c986939c41f9df184aa7d7ed7b2.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;
 }

c3c18c1070041e71199b155a0890bf0e.png

flex item 有哪些属性

以下都是 item 的属性

item 上加 order

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

ab744775eb900b069fbe42795fec53cb.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>

6e32ceeffa5fe50298daa77319ba2450.png

item 上加 flex-grow

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

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

2e5731df7692e3e88d3c87278c7b15e1.png
 .item{
  flex-grow: 1;    /* 每一个 item 平均分配宽度,来占满多余的空间(不是占满整行空间) */
 }

481bab116b8169e9f10fc5234c345fa2.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; }

8dc85486988fcafc395a9a83e5d6d318.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>

6fdcce90c9008085755e769c429f2d6c.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】和【头像】版块,基本不收缩

51d6fb017ab53bb279a9aaa0ce65ec3b.png

flex-basis 控制基准宽度

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

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

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

缩写成 flex

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

daed477953b08ed4be2be4b9b4703e9b.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 */
 }
  • 上述,3个item,宽度为100px
    • grow撑开时每个item平均占满所有多余空间
    • 宽度不足时,2 号主要进行收缩

align-self 定制 align-items

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

4aa1ad2118ab4833b7b99f42d49f09b5.png

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

02516e96352af17c10f4bb3405d252b3.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;
 }

0e0b1179840623b187c67ad7042c0dc9.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;  /* 每个的间距 */
 }

aa105e606774302f2fb050db4d92129c.png
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值