最全面的css布局

1.定位

定位的概念就是它容许你定义一个元素相对于其余正常元素的位置,它应该出如今哪里,这里的其余元素能够是父元素,另外一个元素甚至是浏览器窗口自己。还有就是浮动了,其实浮动并不彻底算是定位,它的特性很是的神奇,以致于它在布局中被人普遍的应用。咱们会在后文中专门说起它的。css

谈及定位,咱们就得从position属性提及。你能准确的说出position的属性值吗?相信你能够完美地说出这么六个属性值:static、relative、absolute、fixed、sticky和inherit。html

  • static(默认):元素框正常生成。块级元素生成一个矩形框,做为文档流的一部分;行内元素则会建立一个或多个行框,置于其父元素中。
  • relative:元素框相对于以前正常文档流中的位置发生偏移,而且原先的位置仍然被占据。发生偏移的时候,可能会覆盖其余元素。
  • absolute:元素框再也不占有文档流位置,而且相对于包含块进行偏移(所谓的包含块就是最近一级外层元素position不为static的元素)
  • fixed:元素框再也不占有文档流位置,而且相对于视窗进行定位
  • sticky:(这是css3新增的属性值)粘性定位,官方的介绍比较简单,或许你不能理解。其实,它就至关于relative和fixed混合。最初会被看成是relative,相对于原来的位置进行偏移;一旦超过必定阈值以后,会被当成fixed定位,相对于视口进行定位。

简单地,介绍一下position的属性值的含义后,在来看一下偏移量top、right、bottom、left四个属性。css3

不清楚,当初在初学css的时候,会不会与margin这个属性混淆?其实,它们之间是很容易去辨识地。由于这四个属性值,实际上是,定位时的偏移量。偏移量不会对static的元素起到做用。而margin,相对应的是盒子模型的外边距,它会对每一个元素框起到做用,使得元素框与其余元素之间产生空白。浏览器

下面:咱们来看一下一些经常使用定位的偏移app

  • relative:它的偏移是相对于原先在文档流中的位置
  • absolute:它的偏移量是相对于最近一级position不是static的祖先元素的
  • fixed:它的偏移量是相对于视口的。

其实,这里说描述的内容,应该都是须要理解的。这些相对于布局来讲是基础的,同时也是很是重要的。须要注意的是,这里的偏移量其实已经涉及到了接下来要说的尺寸。在作自适应布局设计时,每每但愿这些偏移量的单位可以使用百分比,或者相对的单位例如rem等。布局

2.尺寸

那以前上面谈到过尺寸的单位——百分比。那么,下面部分咱们就围绕着尺寸单位展开。字体

尺寸,咱们就应该从单位聊起,对于px这个单位,作网页的应该在熟悉不过了,所以很少作介绍。flex

那么,咱们能够来介绍一下下面几个单位:spa

  • 百分比:百分比的参照物是父元素,50%至关于父元素width的50%
  • rem:这个对于复杂的设计图至关有用,它是html的font-size的大小
  • em:它虽然也是一个相对的单位,相对于父元素的font-size,可是,并不经常使用,主要是计算太麻烦了。

单位只是一个来定义元素大小的相应参考。另外一个概念,或许能够用房子来打一个比方,在早年每幢房子都会在房子的外围建一层栅栏,使得整一块地区能够当作房子+内部地块+栅栏+外围地块的模型。而在css中,每一个元素也会有盒子模型的概念。设计

盒子模型:每一个元素,都会造成一个矩形块,主要包括四部分:margin(外边距)+border(边框)+padding(内边距)+content(内容)

css中存在两种不一样的盒子模型,能够经过box-sizing设置不一样的模型。两种盒子模型,主要是width的宽度不一样

这是标准盒子模型,能够看到width的长度等于content的宽度;而当将box-sizing的属性值设置成border-box时,盒子模型的width=border+padding+content的总和。

能够看出,对于不一样的模型的宽度是不一样的。宽度默认的属性值是auto,这个属性值会使得内部元素的长度自动填充满父元素的width。

 

可是,height的属性值也是默认的auto,为何没有像width同样呢?

其实,auto这个属性值表示的是浏览器自动计算。这种自动计算,须要一个基准,通常浏览器都是容许高度滚动的,因此,会致使一个问题——浏览器找不到垂直方向上的基准。

一样地道理也会被应用在margin属性上。相信若是考察居中时,水平居中你可能闭着眼睛都能写出来,可是垂直居中却绕着脑壳想。这是由于若是是块级元素水平居中只要将水平方向上的margin设置成auto就能够了。可是,垂直方向上却没有这么简单,由于你设置成auto时,margin为0。这个问题,仍是须要仔细思考一下的。

到此为止,布局最基本的部分咱们已经将去大半,还有就是一块浮动。

3.浮动

浮动,这是一个很是有意思的东西,在布局中被普遍的应用。最初,设计浮动时,其实并非为了布局的,而是为了实现文字环绕的特效

可是,浮动并非仅仅这样而已。何为浮动?浮动应该说是‘自成一派’,相似于ps中的图层同样,浮动的元素会在浮动层上面进行排布,而在原先文档流中的元素位置,会被以某种方式进行删除,可是仍是会影响布局。你可能会以为有疑问,什么叫影响布局?咱们能够来举个例子:

 

能够,发现虽然left块由于左浮动,而使得原先元素在文档流中占有的位置被删除,可是,当right块补上原先的位置时,right块中的字体却被挤出来了。这就是所谓的影响布局。

浮动为何会被使用在布局中呢?由于设置浮动后的元素会造成BFC(使得内部的元素不会被外部所干扰),而且元素的宽度也再也不自适应父元素宽度,而是适应自身内容。这样就能够,轻松地实现多栏布局的效果。

浮动的内容还须要介绍一块——清除浮动。能够看到,浮动元素,其实对于布局来讲,是特别危险的。由于你可能这一块作过浮动,但未作清除,那么形成高度塌陷的问题。就是上面图示的那种状况。

清除浮动,最经常使用的方法有两种:

  • overflow: 将父元素的overflow,设置成hidden。
  • after伪类:对子元素的after伪类进行设置。

这里只是稍微的提上一嘴。下面咱们正式来介绍一下网页的布局,本篇最核心的东西。

4.最初的布局——table

最初的时候,网页简单到可能只有文字和连接。这时候,你们最经常使用的就是table。由于table能够展现出多个块的排布。

这种布局如今应该不经常使用了,由于在形色单一时,使用起来方便。可是,如今的网页变得愈来愈复杂,适配的问题也是愈来愈多,这种布局已经再也不时候了。

主要是div块的出现,可使得网页进行灵活的排布,使得网页变得繁荣。这时,开发者也开始思索如何去更加清晰地分辨网页的层次。接下来,咱们能够看看有哪些比较出名的布局方式。

5.两栏布局

是否记得,那些一边主体内容,一边目录的网页,如图:

 

相似于上图的布局,能够定义为两栏布局

两栏布局:一栏定宽,一栏自适应。这样子作的好处是定宽的那一栏能够作广告,自适应的能够做为内容主体。

实现的方式:

  1. float + margin:
<body>
  <div class="left">定宽</div>
  <div class="right">自适应</div>
</body>
.left{
  width: 200px;
  height: 600px;
  background: red;
  float: left;
  display: table;
  text-align: center;
  line-height: 600px;
  color: #fff;
}

.right{
  margin-left: 210px;
  height: 600px;
  background: yellow;
  text-align: center;
  line-height: 600px;
}

 

其余的方法:还可使用position的absolute,可使用一样的效果

6.三栏布局

三栏布局,也是常常会被使用到的一种布局。

它的特色:两边定宽,而后中间的width是auto的,能够自适应内容,再加上margin边距,来进行设定。

三栏布局能够有4种实现方式,每种实现方式都有各自的优缺点。

1.使用左右两栏使用float属性,中间栏使用margin属性进行撑开,注意的是html的结果

<div class="left">左栏</div>
<div class="right">右栏</div>
<div class="middle">中间栏</div>
.left{
  width: 200px;height: 300px; background: yellow; float: left;    
}
.right{
  width: 150px; height: 300px; background: green; float: right;
}
.middle{
  height: 300px; background: red; margin-left: 220px; margin-right: 160px;
}

 

缺点是:1. 当宽度小于左右两边宽度之和时,右侧栏会被挤下去;2. html的结构不正确

2. 使用position定位实现,即左右两栏使用position进行定位,中间栏使用margin进行定位

<div class="left">左栏</div>
<div class="middle">中间栏</div>
<div class="right">右栏</div>
.left{
    background: yellow;
    width: 200px;
    height: 300px;
    position: absolute;
    top: 0;
    left: 0;
}
.middle{
    height: 300px;
    margin: 0 220px;
    background: red;
}
.right{
    height: 300px;
    width: 200px;
    position: absolute;
    top: 0;
    right: 0;
    background: green;
}

 

 

好处是:html结构正常。

缺点时:当父元素有内外边距时,会致使中间栏的位置出现误差

3. 使用float和BFC配合圣杯布局

将middle的宽度设置为100%,而后将其float设置为left,其中的main块设置margin属性,而后左边栏设置float为left,以后设置margin为-100%,右栏也设置为float:left,以后margin-left为自身大小。

<div class="wrapper">
    <div class="middle">
        <div class="main">中间</div>
    </div>
    <div class="left">
        左栏
    </div>
    <div class="right">
        右栏
    </div>
</div>
 
.wrapper{
    overflow: hidden;  //清除浮动
}
.middle{
    width: 100%;
    float: left;
}
.middle .main{
    margin: 0 220px;
    background: red;
}
.left{
    width: 200px;
    height: 300px;
    float: left;
    background: green;
    margin-left: -100%;
}
.right{
    width: 200px;
    height: 300px;
    float: left;
    background: yellow;
    margin-left: -200px;
}

7.弹性布局(flex)

弹性盒子(Flexbox)布局是一种为一维布局而设计的布局方法。一维的意思是你但愿内容是按行或者列来布局。你可使用display: flex来将元素变为弹性布局。

.container {
    display: flex;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

该容器的直接子元素会变为弹性项(flex item),并按行排列。

如图:

7.1. 弹性盒子的轴(axes)

在上面的例子中,咱们会称弹性项在行内是从起始位置开始排列,而不是说它们是左对齐。这些元素会按行排列是由于默认的flex-direction值为rowrow表明了文本的行文方向。因为咱们工做的环境是英文(中文也是如此),一种自左向右的语言,行的开始位置就是在左边,所以咱们的弹性项也是从左边开始的。所以flex-direction的值被定义为弹性盒子的主轴(main axis)。

交叉轴(cross axis)则是和主轴垂直的一条轴。若是你的flex-directionrow而且弹性项是按照行内方向排列的,那么交叉轴就是块级元素的排列方向。若是flex-directioncolumn那么弹性项就会以块级元素排列的方向排布,而后交叉轴就会变为row

若是你习惯于从主轴与交叉轴的角度来使用弹性盒子,那么一切会变得很是简单。

7.2. 方向和次序

弹性盒子模型让咱们能够经过为flex-direction属性设置row-reversecolumn-reverse值来改变主轴上弹性项的方向。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
  flex-direction: row-reverse;
}

.item {
  width: 100px;
  height: 100px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

7.3. 一些Flex的属性

这些flex的属性是用来控制弹性项在主轴上空间大小的。这三个属性是:

  • flex-grow
  • flex-shrink
  • flex-basis

一般可使用它们的简写形式:flex。第一个值表明flex-grow,第二个是flex-shrink,而第三个则是flex-basis

.item {
    flex: 1 1 200px;
}

flex-basis会为弹性项设置未拉伸和压缩时的初始大小。在上面的例子中,大小是200px,所以咱们会给每一个项200px的空间大小。可是大多数状况下容器元素大小不会正好被分为许多200px大小的项,而是可能有一些不足或剩余空间。flex-growflow-shrink属性容许咱们在容器大小不足或有空余时控制各个弹性项的大小。

若是flex-grow的值是任意的正数,那么弹性项会被容许拉伸来占据更多的空间。所以,在上面的例子中,当各项被设为200px后,全部多余的空间会被每一个弹性项平分并填满。

若是flex-shrink的值为任意的正数,那么当弹性项被设置了flex-basis后,元素溢出容器时会进行收缩。在上面这个CSS的例子中,若是容器空间不足,每一个弹性项会等比例缩放以适应容器的大小。

flex-growflex-shrink的值能够是任意的正数。一个具备较大flex-grow值的弹性项会在容器有剩余空间时拉伸更大的比例;而一个具备更大flex-shrink值的项则会在容器空间不足时被压缩的更多。

1 <div class="container">
2   <div class="item">1</div>
3   <div class="item">2</div>
4   <div class="item">3</div>
5 </div>
 1 body {
 2   padding: 20px;
 3   font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
 4 }
 5 
 6 * {box-sizing: border-box;}
 7 
 8 p {
 9   margin: 0 0 1em 0;
10 }
11 
12 .container {
13   width: 500px;
14   border: 5px solid rgb(111,41,97);
15   border-radius: .5em;
16   padding: 10px;
17   display: flex;
18 }
19 
20 .item {
21   flex: 1 1 0;
22   width: 100px;
23   height: 100px;
24   padding: 10px;
25   background-color: rgba(111,41,97,.3);
26   border: 2px solid rgba(111,41,97,.5);
27 }
28 
29 .container :first-child {
30   flex: 2 1 0; 
31 }

8. 网格布局(grid layout)

CSS网格布局(grid layout)是一种用来进行二维布局的技术。二维(two-dimesional)意味着你但愿按照行和列来排布你的内容。和弹性盒子相似,网格布局也须要设置一个display值。你能够为容器元素设置display: grid,而且使用grid-template-columnsgrid-template-rows属性来控制网格中的行与列。

.container {
    display: grid;
    grid-template-columns: 200px 200px 200px;
    grid-template-rows: 200px 200px;
}

上面这段CSS会建立一个行列元素大小固定的网格。不过这也许并非你但愿的。默认值为auto,你能够认为这表明了“让格子尽量的大”。若是你每没有指定行(row track)的大小,全部添加进来的行内容大小都会被置为auto。一种经常使用的模式是为网格制定列宽度,可是容许网格按需添加行。

你可使用任意的长度单位或时百分比来设置行与列,同时你可使用为网格系统所创造的新的单位——frfr是一种弹性单位,它能够指定网格容器内的空间被如何划分。

网格会替你计算与分配空间,你不须要去计算元素的百分比去适应容器大小。在下面这个例子中,咱们使用fr来建立网格的列,这使得网格的列能够自适应。同时咱们还使用了grid-gap来保证元素间的间距(关于网格内元素与的间距会在“对齐”这一部分详细介绍)。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5<br>has more content.</div>
</div>
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

相关文章
相关标签/搜索