CSS-浮动-flex布局

546 阅读9分钟

认识浮动

image.png

浮动的规则:

浮动的规则1:

  • 元素一旦浮动后,就会脱离标准流
    • 朝着向左或者向右方向移动,直到自己的边界,紧贴着包含块(一般是父元素)或者其他浮动元素的边界为止;
    • 定位元素会层叠在浮动元素上面;

image.png

浮动是贴紧自己父元素的边界

浮动规则2:

  • 元素向左(右)浮动,浮动的元素左(右)边界,是不能超出包含块的左(右)边界;

image.png

浮动规则3:

  • 浮动元素之间不能层叠!
    • 如果一个元素浮动,但是另一个元素已经在那个位置了,后浮动的元素将会紧贴着前一个浮动的元素(左浮动找左浮动,右浮动找右浮动);
    • 如果水平方向剩余的空间不够显示浮动元素,浮动元素将会向下移动,直到有充足的空间为止;
item{
    //3个全部向左浮动,全部都会脱离标准流,但是会紧挨着前面的浮动元素,并不覆盖;
    float:left;
}

<div class="item box1"></div>
<div class="item box2"></div>
<div class="item box3"></div>

image.png

浮动规则4:

  • 浮动元素不能与行内级内容层叠,行内级内容将会被浮动元素推出!
    • 比如行内级元素、inline-block元素、块级元素的文字内容;

image.png

.box{
    
}
.box img{
    //图文环绕,但是只能在当前这一行(左右)浮动
    float:left
    //往上浮动的话,就需要把img标签放在顶部;   
}

<div class="box">
    。。。文字
    <img.....>
    。。。文字
</box>

浮动规则5:

  • 行内级元素、inline-block元素再浮动后,顶部将会与所在行的顶部对齐:

image.png

额外补充

<div class="box">
    <span>111</span>
    <span>222</span>
    <span>333</span>
</div>

默认多个行内级元素之间是会存在一定的间隙的

多个行内级元素中间的空格(间隙)去除的方法:

  • 删除换行符(不推荐)
  • 将父元素中的font-size设置为0,但是需要子元素设置回来(不推荐)
  • 通过浮动属性(因为浮动元素不能层叠,会紧挨着)
  • flex布局(最终答案)

京东布局

设置负的margin值:

    <style>
        /* 公共的class */
        .content {
            width: 1190px;
            margin: 0 auto;
            background-color: orange;
            height: 800px;
        }

        /* 布局样式 */
        .item {
            width: 230px;
            height: 322px;
            background-color: purple;

            /* 浮动,因为div item是块级,浮动会就会层叠在一行 */
            float: left;
            margin-right: 10px;
        }

        /* 让content的宽高不变,而box的宽变为1200 */
        .box {
            margin-right: -10px;
        }
    </style>
</head>

<body>
    <div class="content">
        <div class="box">
            <div class="item item1">1</div>
            <div class="item item1">2</div>
            <div class="item item1">3</div>
            <div class="item item1">4</div>
            <div class="item item1">5</div>
        </div>
    </div>
</body>

浮动的问题-高度塌陷

由于浮动元素会脱离标准流,变成脱标元素,所以不再向父元素汇报高度;

  • 父元素计算高度时,就不会计算浮动子元素的高度,就会导致高度塌陷的问题;
  • 解决父元素高度塌陷的问题过程,一般叫清浮动(清理浮动、清除浮动)
  • 清除浮动的目的是:让父元素计算总高度的时候,把浮动子元素的高度算进去

如果我父元素写的高度,但是子元素浮动超出了这个高度范围,那么其他元素在固定时,就会直接在父元素下面(可能会和超出高度的子元素浮动重叠),因为是浮动,脱离标准流,所以会出现这种情况,除非我们自动手动写上父元素的正确高度。

如何清除浮动呢?

  • 使用clear属性

clear属性:可以制定一个元素是否必须移动(清除浮动后)到它之前的浮动元素下面

就是必须移动到我们浮动元素的下面

通常我们会在父元素增加最后一个空的块级子元素,并且设置clear:both,这样其他元素就不会产生塌陷,但是会增加很多无意义的空标签;

clear的常用取值:

  • left:要求元素的顶部低于之前生成的所有左浮动元素的底部;
  • right:要求元素的顶部低于之前生成的所有右浮动元素的底部;
  • both:要求元素的顶部低于之前生成的所有浮动元素的底部(不仅在左浮动下面,而且还在右浮动下面,同时满足);
  • none:默认值,无特殊要求

实际上无论是给父元素固定宽度还是给父元素最后一个添加clear:both,我们都不推荐,更好的方法是给父元素添加一个伪元素

父元素添加伪元素解决塌陷

给父元素添加伪类,因为::after每次都是最后一个

.__::after{
    content:"";
    //因为伪元素是行内级非替换,没有宽度的,要变成块级,才能独占一行
    display:block;
    clear:both;
    
    visibility:hidden;//浏览器兼容性
    height:0;//浏览器兼容性
}
.__{
   *zoom:1;//IE6/7兼容性 
}

image.png

认识flexbox

image.png

image.png

flex item不再严格区分块级和行内级,但是大的盒子(flex container)还是区分的

flex布局的模型

image.png

默认情况下,item都是沿着主轴方向排布的,主轴的方向默认就是在flex container中从左往右的方向;

也就是说主轴的方向是可以修改的,修改后,item的布局方向也就随之变化

交叉轴:默认是从上往下的方向,和主轴是不同的概念;默认情况下,如果一行中有多个item,那么flex会将item压缩,直至满足大盒子的宽,但是我们希望的时候在一定数量的item后,就应该顺着往下排了,那么这个时候就会用到【交叉轴】

image.png

总之:交叉轴主要是用来让item换行的

沿着主轴的开始位置是:main start
沿着主轴的结束位置是:main end
沿着交叉轴开始位置是:cross start
沿着交叉轴结束位置是:cross end

image.png

flex container上的属性

flex-direction

flex items默认是沿着主轴main start开始,往main end方向排布;

flex-direction决定了主轴的方向,有4个取值:

  • row(默认值:从左往右)
  • row-reserve(从右往左)
  • column(从上往下)
  • column-reverse(从下往上)
.container{
    width:500px;
    height:500px;
    display:flex;
    
    flex-direction:row-reserve;
}

.item{
    width:120px;
    height:120px;
    
}

<div class="container">
    <div class="item item1"></div>
    <div class="item item1"></div>
    <div class="item item1"></div>
</div>

flex-wrap

flex-wrap:决定了flex container是单行还是多行,如果是单行,无论有多少个items都会压缩在一行中;

  • nowarp(默认):单行
  • wrap:多行
  • wrap-reserve

简写

flex-flowflex-directionflex-wrap的简写,顺序任何,还可以省略;

flex-flow:warp; 

justify-content

justify-content决定了flex items主轴上的对齐方式;

  • flex-start(默认值):与main start对齐
  • flex-end:与main end对齐
  • center:居中对齐
  • space-between(用的最多):
    • flex items之间的距离相等;
    • main start、main end两端对齐;
  • space-around
    • flex items之间的距离相等;
    • flex itemsmain start、main end之间的距离是flex items之间距离的一半;
  • space-evently
    • flex items之间的距离相等;
    • flex itemsmain start、main end之间的距离等于flex items之间的距离

image.png

.container{
    display:flex;
    justify-content:space-between;
}

.items{
    //自己可以添加margin...
}

align-item

align-items决定了flex items交叉轴上的对齐方式;

  • normal(默认):在弹性布局中,效果和stretch一样;
  • stretch:当flex items在交叉轴方向的size为auto时,会自动拉伸填充flex container;
  • flex-start:与cross start对齐
  • flex-end:与cross end对齐
  • center(用的最多):居中对齐
  • baseline:与基准线对齐

image.png

.container{
    display:flex;
    //justify-content:space-between;
    align-item:center;
}

字体文字变大时,基线也是会变的;

align-content

align-content决定了多行flex items在交叉轴上的对齐方式,用法与justify-content类似;

  • stretch:与align-items的stretch类似
  • flex-start:与cross start对齐
  • flex-end:与cross end对齐
  • center:居中对齐
  • space-between:
    • flex items之间的距离相等
    • 与cross start、cross end两端对齐
  • space-around:
    • flex items之间的距离相等
    • flex items与cross start、cross end之间的距离是flex items之间距离的一般;
  • space-evently:
    • flex items之间的距离相等
    • flex items与cross start、cross end之间的距离等于flex items之间的距离;

image.png

flex item上的属性

放在item上的属性用的比较少;

flex-item属性-order

order决定了flex items的排布顺序

  • 可以设置任意整数(正整数、负整数、0),值越小,就排在前面
  • 默认值是0

image.png

flex-item属性-flex items

flex items可以通过align-self覆盖flex container设置的align-items

  • auto(默认值):遵从flex containeralign-items设置
  • stretch、flex-start、flex-end、center、baseline,效果跟align-items是一样的;

image.png

flex-item属性-flex-grow

当我items过多的时候,flex会将这些items全部压缩并且只填充一行,但是当我items过少的时候,flex又不能将我们拉伸,合理的填充一行,所以这个时候flex-grow出现了;

flex-grow决定了flex items如何扩展(拉伸/成长)

  • 可以设置任意非负数字(正小数、正整数、0),默认值是0(不给多余空间);
  • 当flex container在主轴方向上有剩余size时,flex-grow属性才会生效;
  • 如果所有的flex-items的flex-grow总和sum超过1,每个flex item扩展的size为:
    • flex container的剩余size*flex-grow/sum;
    • flex items扩展后的最终size,不能超过max-width/max-height;
.container{
    display:flex
}

.item{
    //如果只有一个元素使用这个类,那么剩余空间会全部给他拉伸
    flex-grow:1
    //如果每个元素都使用这个类,那么剩余空间会平均分给他们,拉满这行
}

如果有3个小盒子,每个小盒子的flex-grow都是1,那么将剩下的部分分为3份,如果其中一个是2,其余两个盒子是1,那么加起来为4,就是分为4份,2的占2份,1的占1份;

image.png

flex-item属性-flex-shrink

flex-grow和flex-shrink对应,一个拉伸,一个压缩

flex-shrink决定了flex items如何收缩(缩小)

  • 可以设置任意非负数字(正小数、正整数、0),默认值是1(默认就是可以压缩);
  • 当flex items在主轴方向超过了flex container的size,那么flex-shrink才会生效;

如果所有的flex items的flex-shrink总和超过1,每个flex item收缩的size为:

  • flex items超出flex container的size * 收缩比例 / 所有flex items的收缩比例之和

flex items收缩后的最终size不能小于min-width/min-height

flex-item属性-flex-basis

flex-basis用来设置flex items在主轴方向的base size(基础尺寸)

  • auto(默认值)、具体的宽度数值(100px)
.container{
    display:flex
}

.item{
    //这个是基础尺寸
    width:120px;(写死宽度是120)
    flex-basis:120px;(内容过多时,他可能会自动拓宽拉伸)
}

决定flex items最终base size的因素,优先级从高到低:

  • max-width/max-height/min-width/min-height
  • flex-basis
  • width/height
  • 内容本身的size

flex-item属性-flex属性

flex是flex-growflex-shrinkflex-basis的简写,flex属性可以指定1个、2个或3个值;

image.png

flex:1 1 10px

例题

image.png

由于使用了justify-content:space-between,如果某一行items少的话,排布就会不均匀,不美观,我们通常会:添加span,并且span的个数是列数-2。用i标签也可以

image.png