你尚未登录,仅允许查看本站部分内容。请登录使用邀请码注册
Fonda

关于布局 —— Position、Float、Flexbox、负边距 0个回复 专栏 @ CSS

Fonda 发布于 2 月前

Position布局

<div class="wrapper">
 <div class="left"></div>
 <div class="main"></div>
 <div class="right"></div>
</div>
// normalized...
// ...

// position布局
.wrapper {
 position: relative;

 // wrapper的高度必须要比left/right的高度高
 //height: 600px;
}
.left,
.right {
 position: absolute;
 top: 0;
 width: 200px;
}
.left {
 left: 0;
 background-color: #F00;
}
.right {
 right: 0;
 background-color: #0F0;
}
.main {
 margin: 0 210px;
 background-color: #00F;
}

上面那种方法是传统的绝对定位布局,简单粗暴,且这种布局不太会影响元素内部的布局。但若没有给wrapper设置min-width的话,leftright会因浏览器窗口变小,main的空间从有到无,然后两者就被重叠在一起了。

这里记录一下定位相关的知识点

absolute

  1. 包裹性 包裹性简单点说就是inline-block化,即当前元素若被设置成absolute后,则其默认100%显示的元素便会被设置成自适应内部元素的宽度。

  2. 破坏性 破坏性换句话说就是指父元素塌陷,不同于margin collapse仅会造成高度塌陷, absolute造成的塌陷会让其父元素宽高都塌掉(float仅会让高度塌陷)。

  3. z-index
    被设置了absolute的子元素不存在文档流中,不管其static兄弟元素的z-index被设置成多大,都不会覆盖掉absolute元素,除非,absolute元素的z-index被设置成负值。

  4. transform
    如果含有overflow不为visible的父级元素,同时,该父级元素以及到该绝对定位元素之间任何嵌套元素都没有position为非static属性的声明,则overflow对该absolute元素不起作用。
    这一个解释起来比较拗口,举个例子(转自张鑫旭博客):

<p><strong>图片自身transform</strong></p>
<div class="overflow">
    <img src="mm1.jpg" class="transform" />
</div>
<p><strong>overflow容器transform</strong></p>
<div class="overflow transform">
    <img src="mm1.jpg" />
</div>
<p><strong>overflow和图片之间内嵌元素transform</strong></p>
<div class="overflow">
    <div class="transform">
        <img src="mm1.jpg" />
    </div>
</div>
.overflow { width: 191px; height: 191px; border: 2px solid #beceeb; overflow: hidden; }
.overflow img { position: absolute; }
.transform { -webkit-transform: scale(1); -ms-transform: scale(1); transform: scale(1); }

Float布局

<div class="left"></div>
<div class="right"></div>
<div class="content"></div>
.left, .right {
 width: 100px;
 height: 100px;
}
.left {
 background-color: #F00;
 float: left;
}
.right {
 background-color: #0F0;
 float: right;
}
.content {
 background-color: #00F;
 height: 500px;
 margin: 0 200px;
}

知识点整理:

1、float是一个带有方向的inline-block属性,换句话来说,就是98%的display:inline-block;float:left;都不需要display:inline-block;,因为float会自动将其子元素包裹住。

2、float的元素会覆盖掉后面的兄弟block元素,且设置z-index无效。
(后来我才知道,专业点的解释应该从BFC特性的角度去解释,因为BFC不会与浮动的盒子叠加233...)
来个栗子:

<div class="wrap">
 <div class="float">
  <!-- <img src="" alt=""> -->
 </div>
 <div class="block">
  <!-- <img src="" alt=""> -->
 </div>
</div>
.wrap {
 width: 500px;
 height: 500px;
 boder: 1px solid #CCC;
}
.float, .block {
 width: 100px;
 height: 100px;
}
.float {
 float: left;
 background-color: #F00;
}
.block {
 background-color: #0F0;

 // 试着加上这个属性看看,(因为inline-block触发了BFC,等同于overflow:hidden...)
 // display: inline-block;
}

为什么加上了inline-block布局就不一样了呢?因为float设计的初衷就不是为了布局的,而是文字环绕。
但这里要注意一点,若div里面加个img元素,img彼此是不会重叠的,因为图片是个实体,无法与同样实体且同一文档流的图片重合,所以这里的图片会像文字一样环绕周围。

3、清除浮动clearance
清除浮动有很多种方法,但各有优劣,选取那种方法得看项目取舍。

IE下的清除浮动比较简单,触发元素的haslayout就可以了。如宽度值,高度值,绝对定位,zoom,浮动本身都可以让元素haslayout。显然,首选zoom:1;不会干扰任何样式。非IE浏览器则是触发BFC,常用的是overflow属性,overflow:hidden;或是overflow:scroll都可以,不过由于后者经常一不小心出现滚动条,所以前者用的更多些。由于现代浏览器都支持after伪类伪元素,所以常常也会用after写入一个clear属性的元素清除浮动。当然,最投机取巧的方法就是直接一个<div style="clear:both;"></div>放到当作最后一个子标签放到父标签那儿。

.clearfix {
 overflow: hidden;
 zoom: 1;
}
<!-- ------------- -->
.clearfix {
 zoom: 1;
}
.clearfix:after,
.clearfix:before {
 display: block;
 content: '';
 line-height: 0;
 clear: both;
 visibility: hidden;
}

4、关于BFC

浮动,绝对定位元素,inline-blocks, table-cells, table-captions,和overflow的值不为visible的元素,(除了这个值已经被传到了视口的时候)将创建一个新的块级格式化上下文。

一个BFC是一个HTML盒子并且至少满足下列条件中的任何一个:

  • float的值不为none
  • position的值不为static或者relative
  • display的值为 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一个
  • overflow的值不为visible

    使用BFC来防止外边距折叠

    毗邻块盒子的垂直外边距折叠只有他们是在同一BFC时才会发生。如果他们属于不同的BFC,他们之间的外边距将不会折叠。所以通过创建一个新的BFC我们可以防止外边距折叠。

    使用BFC来包含浮动

    浮动元素会脱离line boxes,因为这个原因,导致元素没有高度,也就无法撑高父元素。而我们通常会使用clear:both来清除浮动带来的高度塌陷,但其实我们也可以用BFC。

负margin布局

负margin布局即是传说中的双飞翼布局。

<div class="marginWrap">
 <div class="content"></div>
</div>
<div class="left"></div>
<div class="right"></div>
.marginWrap {
 width: 100%;
 float: left;
}
.left, .right {
 width: 180px;
 height: 500px;
 background-color: #F00;
}
.content {
 margin: 0 200px;
 height: 500px;
 background-color: #0F0;
}
.left {
 margin-left: -100%;
 float: left;
}
.right {
 margin-left: -180px;
 float: left;
}

注意:

  1. 盒子最后的显示大小等于盒子的border+padding+正margin,而负margin不会影响其大小。

  2. margin-left、top不论正负元素自己动,right、bottom不论正负别的元素动。

扩展资料:

Web布局连载——两栏固定布局(一)

Web布局连载——两栏固定布局(二)

Web布局连载——两栏固定布局(三)

Flexbox布局

<div class="wrap">
 <div class="content"></div>
 <div class="left"></div>
 <div class="right"></div>
</div>
.wrap {
 display: flex;
}
.left, .right, .content {
 height: 500px;
}
.left {
 width: 200px;
 order: 1;
 background-color: #F00;
}
.content {
 flex: 1;
 order: 2;
 background-color: #0F0;
}
.right {
 width: 200px;
 order: 3;
 background-color: #00F;
}

参考资料:

阮一峰 - Flex 布局教程:语法篇

阮一峰 - Flex 布局教程:实例篇

A grid system based on the flex display property(source)

CSS Flexible Box Layout Module Level 1

w3cplus Flex系列

Flexbox在微信浏览器上有非常多的坑, 这里有一个小归纳,可以参考一下2016-3-17

等待第一条回复
登录后回复,如无账号,请使用邀请码注册