资讯专栏INFORMATION COLUMN

CSS查漏补缺

smallStone / 3327人阅读

摘要:而圣杯布局跟双飞翼布局就是能够不考虑主体的位置,能够只通过代码就改变相应的布局,这也是优点之一。如果在圣杯布局的基础上,给它一个多余的标签,把包起来,这就是双飞翼布局。这里有个尝试页面,利用双飞翼,实现了一套栅格化布局系统。

块级格式上下文(Block formatting context)

普通流(Normal Flow)

在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行, 除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。

浮动 (Floats)

在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能的向左边或右边偏移,其效果与印刷排版中的文本环绕相似。

绝对定位 (Absolute Positioning)

在绝对定位布局中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响(如果看了上文的童鞋,会发现这点与浮动元素会影响兄弟元素是不同的),而元素具体的位置由绝对定位的坐标决定。

BFC 正是属于普通流的,因此它对兄弟元素也不会造成什么影响。

什么是BFC?

块格式化上下文(block formatting context) 是页面 CSS 视觉渲染的一部分。它是用于决定块盒子的布局及浮动相互影响的一个区域。 --MDN 块格式上下文

我的理解是,BFC是一个环境,在这个环境中的元素不会影响到其他环境中的布局,也就是说,处于不同BFC中的元素是不会互相干扰的。

BFC的触发条件

根元素或其它包含它的元素

浮动元素,float除none以外的值

绝对定位元素 (元素的 position 为 absolute 或 fixed)

display为以下其中之一的值:inline-block,table-cell,table-caption

overflow 的值不为 visible的元素

弹性盒子 flex boxes (元素的 display: flex 或 inline-flex)

其中,最常见的就是overflow:hidden、float:left/right、position:absolute。也就是说,每次看到这些属性的时候,就代表了该元素以及创建了一个BFC了。

BFC的特性

内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流);

处于同一个BFC中的元素相互影响,可能会发生margin collapse;

每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此;

BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;

计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算;

浮动盒区域不叠加到BFC上;

BFC有什么用?

阻止外边距折叠

两个相连的块级元素在垂直上的外边距会发生叠加,有些把这种情况看作是bug,但我觉得可能是出于段落排版的考虑,为了令行间距一致才有的这一特性。我们先来看看例子:

first

second

*{margin: 0px;padding: 0px}
p {
    color: red;
    background: #eee;
    width: 100px;
    height: 100px;
    line-height: 100px;
    text-align: center;
    margin: 10px;
    border: solid 1px red;
}

从上面可以看出,我们给两个p元素都设置margin,但中间的间距却发生了折叠。然后举个BFC的例子:

.ele{
    overflow: hidden;
    border: solid 1px red;
}

first

second

从上面可以看出,我们为每个div元素设置overflow的值为hidden,产生一个块级格式上下文,因为外边距不会相互重叠。

BFC可以包含浮动的元素

//html
float
float

float
float
*{margin: 0px;padding: 0px}
.floatL{
    float: left;
    width: 100px;
    height: 100px;
    background-color: red;
    text-align: center;
    line-height: 100px;
}
.box{
    border: 1px solid red;
    width: 300px;
    margin: 100px;
    padding: 20px;
}
.BFC{
    overflow: hidden;
    *zoom: 1;
}

从运行结果可以看出,如果块级元素里面包含着浮动元素会发生高度塌陷,但是将它变成一个BFC后,BFC在计算高度时会自动将浮动元素计算在内。

BFC可以阻止元素被浮动元素覆盖

box1
box2
*{margin: 0px; padding: 0px}

.box1{
    width: 100px;
    height: 100px;
    line-height: 100px;
    text-align: center;
    background-color: rgba(0, 0, 255, 0.5);
    border: 1px solid #000;
    float: left;
}
.box2{
    width: 200px;
    height: 200px;
    line-height: 100px;
    text-align: center;
    background-color: rgba(255, 0, 0, 0.5);
    border: 1px solid #000;
    /* overflow: hidden; */
    /* *zoom: 1; */
}

从上面看出,当元素浮动后,会与后面的块级元素产生相互覆盖。那怎么解决这个问题,只要为后面的元素创建一个BFC。添加overflow属性到box2上。

overflow: hidden;
*zoom: 1;

这样子阻止了浮动元素重叠的问题。

BFC与hasLayout

除了使用 overflow: hidden 触发 BFC 外,还使用了一个 *zomm: 1 的属性,这是 IEhack ,因为 IE6-7 并不支持 W3C 的 BFC ,而是使用私有属性 hasLayout 。从表现上来说,hasLayout 跟 BFC 很相似,只是 hasLayout 自身存在很多问题,导致了 IE6-7 中一系列的 bug 。触发 hasLayout 的条件与触发 BFC 有些相似,推荐为元素设置 IE 特有的 CSS 属性 zoom: 1 触发 hasLayoutzoom 用于设置或检索元素的缩放比例,值为“1”即使用元素的实际尺寸,使用 zoom: 1 既可以触发 hasLayout 又不会对元素造成其他影响,相对来说会更为方便。

拓展阅读:

Block formatting context(块级格式化上下文)

学习块格式化上下文

BFC与hasLayout

清除浮动

经典的清除浮动:

//利用伪元素清除浮动
.clearfix:after {
     content:"."; 
     display:block; 
     height:0; 
     visibility:hidden; 
     clear:both; 
}
.clearfix { 
    *zoom:1; 
}

拓展阅读:
那些年一起清除过的浮动

认识圣杯布局和双飞翼布局

各种各样的布局,无非就是用了浮动 float,负边距,相对定位,通过这三者的巧妙组合跟拼凑来实现的。用好这些,布局就会很简单。

还没学会布局时,就听到有圣杯布局和双飞翼布局,这布局都有这么风骚的名字,就觉得很酷,事实也如此,了解了圣杯布局和双飞翼布局,才发现挺深奥的。

传统的布局中,当我们需要改变两栏的互换,就会很麻烦。因为还要涉及到 HTML 代码的修改,不能完全从 CSS 上更改,这叫 HTML 和 CSS 的耦合。而圣杯布局跟双飞翼布局就是能够不考虑主体的位置,能够只通过 CSS 代码就改变相应的布局,这也是优点之一。

圣杯布局

试试这样的HTML结构:

header
main
sub
extra

给它加上CSS样式:

body{ margin: 0; padding: 0; font-size: 1.5em; font-weight: bold; min-width: 500px;}
.header,.footer{ text-align: center;}
.header{ height: 50px; background-color: #76ffff;}
.footer{ height: 50px; background-color: #ff7676;}
.main{ background-color: #666;}
.sub{ background-color: #44fa44;}
.extra{ background-color: #3dbdff;}
/*start*/
.main{
    width: 100%;
    float: left;
}
.sub{
    width: 100px;
    float: left;
    margin-left: -100%;
}
.extra{
    width: 200px;
    float: left;
    margin-left: -200px;
}
.container{
    overflow: hidden;
}

结果如下:

会发现,main的位置不正确,所以再给container加上 padding: 0 200px 0 100px;

虽然 main 的位置正确了,可是 sub 和 extra 位置优点不对,所以我们再用上相对定位,为 subextra 加上如下代码:

.sub{
    position: relative;;
    left: -100px;
}
.extra{
    position: relative;
    right: -200px;
}

效果就出来了,

噢耶,这就是圣杯布局。如果在圣杯布局的基础上,给它一个多余的标签,把 mian 包起来,这就是双飞翼布局。

双飞翼布局

HTML结构:

header
main
sub
extra

CSS结构:

body{ margin: 0; padding: 0; font-size: 1.5em; font-weight: bold; min-width: 500px;}
.header,.footer{ text-align: center;}
.header{ height: 50px; background-color: #76ffff;}
.footer{ height: 50px; background-color: #ff7676;}
.main{ background-color: #666;}
.sub{ background-color: #44fa44;}
.extra{ background-color: #3dbdff;}
/*start*/
.main{
    width: 100%;
    height: 100px;
    float: left;
}
.sub{
    width: 100px;
    height: 100px;
    float: left;
    margin-left: -100%;
}
.extra{
    width: 200px;
    height: 100px;
    float: left;
    margin-left: -200px;
}
.main-wrap{
    margin: 0 200px 0 100px;
}
.container{
    height: 100px;
    overflow: hidden;
    *zoom: 1;
}

可以看到,只要为包住 main-wrap 设置 margin,连相对定位都没用到,效果就出来了。

如果把三栏布局比作一只大鸟,可以把main看成是鸟的身体,sub和extra则是鸟的翅膀。这个布局的实现思路是,先把最重要的身体部分放好,然后再将翅膀移动到适当的地方。因此请容许我给这个布局实现取名为双飞翼布局(Flying Swing Layout).
就如上图中的鸟有各种姿势一样,利用双飞翼布局,我们也可以实现各种布局。这里有个尝试页面,利用双飞翼,实现了一套栅格化布局系统。

优点:

实现了内容与布局的分离,这是渐进式增强布局的思想,从内容出发,不考虑布局。

main部分是自适应宽度的,很容易在定宽布局和流体布局中切换。

任何一栏都可以是最高栏,不会出问题。

需要的hack非常少(就一个针对ie6的清除浮动hack:_zoom: 1;)
在浏览器上的兼容性非常好,IE5.5以上都支持。

缺点:

main需要一个额外的包裹层。

normalize.css和reset.css

normalize 的理念则是尽量保留浏览器的默认样式,不进行太多的重置。

reset 的目的,是将所有的浏览器的自带样式重置掉,这样更易于保持各浏览器渲染的一致性。

/* reset */
html,body,h1,h2,h3,h4,h5,h6,div,dl,dt,dd,ul,ol,li,p,blockquote,pre,hr,figure,table,caption,th,td,form,fieldset,legend,input,button,textarea,menu{margin:0;padding:0;}
header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block;}
table{border-collapse:collapse;border-spacing:0;}
caption,th{text-align:left;font-weight:normal;}
html,body,fieldset,img,iframe,abbr{border:0;}
i,cite,em,var,address,dfn{font-style:normal;}
[hidefocus],summary{outline:0;}
li{list-style:none;}
h1,h2,h3,h4,h5,h6,small{font-size:100%;}
sup,sub{font-size:83%;}
pre,code,kbd,samp{font-family:inherit;}
q:before,q:after{content:none;}
textarea{overflow:auto;resize:none;}
label,summary{cursor:default;}
a,button{cursor:pointer;}
h1,h2,h3,h4,h5,h6,em,strong,b{font-weight:bold;}
del,ins,u,s,a,a:hover{text-decoration:none;}
body,textarea,input,button,select,keygen,legend{font:12px/1.14 arial,5b8b4f53;color:#333;outline:0;}
body{background:#fff;}
a,a:hover{color:#333;}

以上reset来自NEC的css reset。

拓展阅读:
Normalize.css 和 Reset CSS 有什么本质区别?

IE条件注释

IE条件注释是一种特殊的HTML注释,这种注释只有IE5.0及以上版本才能理解。比如普通的HTML注释是:


  而只有IE可读的IE条件注释是:

  “非IE条件注释”:
 non-IE HTML Code 
  “非特定版本IE条件注释”(很少用到):

Code for browsers that match the if condition

简而言之,除了“Windows上的IE”之外的所有浏览器都会认为条件注释只是一段普通的HTML注释。你不能在CSS代码中使用条件注释。IE条件注释是很有用的对IE隐藏或者展现特定代码的方法,比起在CSS中用诡异的_/制造bug,利用IE条件注释来写CSS “hacks”是更合理的方法。通俗点,条件注释就是一些if判断,但这些判断不是在脚本里执行的,而是直接在html代码里执行的。

条件注释的基本结构和HTML的注释()是一样的。因此IE以外的浏览器将会把它们看作是普通的注释而完全忽略它们。

IE将会根据if条件来判断是否如解析普通的页面内容一样解析条件注释里的内容。

条件注释使用的是HTML的注释结构,因此他们只能使用在HTML文件里,而不能在CSS文件中使用。

从语法上看这是相当合法的普通HTML注释。任何浏览器都会认为之间的部分是注释从而忽略它。但是IE也会看到其中[if IE]>,从而开始解释接下来的代码直到遇到

通过“比较操作符”可以更灵活地对IE版本进行控制,用法是在IE前面加上“比较操作符”。合法的操作符如下:

lte:就是Less than or equal to的简写,也就是小于或等于的意思。

lt :就是Less than的简写,也就是小于的意思。

gte:就是Greater than or equal to的简写,也就是大于或等于的意思。

gt :就是Greater than的简写,也就是大于的意思。

! :就是不等于的意思,跟javascript里的不等于判断符相同

 / 如果IE版本大于5.5 /
 / 如果IE版本小于等于6 /
 / 如果浏览器不是IE /

常用的IE条件注释











水平垂直居中的各种方案 行内元素的水平居中

要实现行内元素的水平居中,只需把行内元素包裹在块级父层元(

  • 等)中,并且在父层元素CSS设置如下:

    .container{
      text-align: center;
    }

    demo

    块状元素的水平居中

    要实现块状元素(display:block)的水平居中,我们只需要将它的左右外边距margin-left和margin-right设置为auto,即可实现块状元素的居中,要水平居中的块状元素CSS设置如下:

    .container{
        margin: 0 auto;
    }

    demo

    已知高度宽度元素的水平垂直居中 1. 利用绝对定位与负边距实现。

    利用绝对定位,将元素的top和left属性都设为50%,再利用margin边距,将元素回拉它本身高宽的一半,实现垂直居中。核心CSS代码如下:

    .container{
        position: relative;
    }
    .center{
        position: absolute;
        left: 50%;
        top: 50%;
        margin: -50px 0 0 -50px;
    }

    demo

    2. 利用绝对定位和margin
    .container{
      position: relative;
    }
    .center{
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      margin: auto;
    }

    demo

    未知高度和宽度元素的水平垂直居中 1. 被居中的元素是inline或者inline-block元素

    可以巧妙的将父级容器设置为display:table-cell,配合text-align:centervertical-align:middle即可以实现水平垂直居中。

    .container{
      width: 600px;
      height: 600px;
      background: #eee;
      display: table-cell;
      text-align: center;
      vertical-align: middle;
    }
    .center{
      background: blue; 
    }

    demo

    2. 利用CSS3的transform的属性

    利用C3的transform,可以轻松的在未知元素的高宽的情况下实现元素的垂直居中。

    .container{
      width: 100%;
      height: 400px;
      background: #eee;
      position: relative;
    }
    .center{
      background: blue;
      position:absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }

    demo

    3. flex布局

    使用flex布局,无需绝对定位等改变布局的操作,可以轻松实现元素的水平垂直居中。

    .container{
      width: 100%;
      height: 400px;
      background: #eee;
      /* flex 布局解决水平居中 */
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .center{
      width: 100px;
      height: 100px;
      background: blue;
      text-align: center;
    }

    demo

    notes:CSS3的transform和flex有兼容性问题。ie11+才支持flexbox布局。
  • 文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

    转载请注明本文地址:https://www.ucloud.cn/yun/111417.html

    相关文章

    • 前端背景知识查漏补缺

      摘要:提交内容可以是一个提议想法初步描述该阶段是对所提交新特性的正式建议。在这个阶段需具备以下条件指定一名成员作为审阅通过有实现的或者初步编写标准,包括问题描述解决方案示例语法语义关键的算法及抽象实现在的复杂度等该阶段是会出现标准中的第一个版本。 ECMAScript 与 JavaScript ECMAScript 是一套脚本语言的规范,内部编号 ECMA-262 该规范由 Ecma(Eu...

      developerworks 评论0 收藏0
    • 前端背景知识查漏补缺

      摘要:提交内容可以是一个提议想法初步描述该阶段是对所提交新特性的正式建议。在这个阶段需具备以下条件指定一名成员作为审阅通过有实现的或者初步编写标准,包括问题描述解决方案示例语法语义关键的算法及抽象实现在的复杂度等该阶段是会出现标准中的第一个版本。 ECMAScript 与 JavaScript ECMAScript 是一套脚本语言的规范,内部编号 ECMA-262 该规范由 Ecma(Eu...

      incredible 评论0 收藏0
    • CSS查漏补缺

      摘要:错误的原因是选择器的权值不能进位。第一个值设置宽度,第二个值设置高度,如果只设置一个值,则第二个值会被设置为。 css样式优先级 !important > 内联样式 > ID 选择器 > 类选择器 = 属性选择器 = 伪类选择器 > 标签选择器 = 伪元素选择器 在学习过程中,你可能发现给选择器加权值的说法,即 ID 选择器权值为 100,类选择器权值为 10,标签选择器权值为 ...

      FrancisSoung 评论0 收藏0
    • 【面试篇】JS基础知识查漏补缺

      摘要:因为在页面加载完成后,引擎维护着两个队列,一个是按页面顺序加载的执行队列,还有一个空闲队列,使用定时函数就是将回调函数加入到空闲队列中,故和其他定时器是并发执行的。 1.window.onload和$(document).ready()的区别: ①执行时间:window.onload会在所有元素,包括图片,引用文件加载完成之后执行,而$(document).ready()则会在HTML...

      myeveryheart 评论0 收藏0
    • 查漏补缺 - 收藏集 - 掘金

      摘要:酝酿许久之后,笔者准备接下来撰写前端面试题系列文章,内容涵盖浏览器框架分钟搞定常用基础知识前端掘金基础智商划重点在实际开发中,已经非常普及了。 这道题--致敬各位10年阿里的前端开发 - 掘金很巧合,我在认识了两位同是10年工作经验的阿里前端开发小伙伴,不但要向前辈学习,我有时候还会选择另一种方法逗逗他们,拿了网上一道经典面试题,可能我连去阿里面试的机会都没有,但是我感受到了一次面试1...

      YuboonaZhang 评论0 收藏0

    发表评论

    0条评论

    最新活动
    阅读需要支付1元查看
    <