css布局那点事

原文地址: http://tt-ghost.github.io/2016/07/14/css布局那点事

说到布局,一定离不了自身的尺寸、文档流、相邻元素、父元素等。目的是让元素显示在应该出现的位置(好像是废话),然后其他地方最好也能复用,如果不同分辨率上体验一致就更好了

针对上面这个目的,接下来我们就开始讲讲怎么让元素显示在应该在的位置,开始正题:

<h1 style='text-align:center'>理论部分</h1>


需要知道的基础知识

以下知识点需要有所了解

默认样式

浏览器对所有标签都有默认样式,比如文字默认是黑色,div默认是 <code>block</code>(块)元素,span默认是 <code>inline</code> (行内)元素等

属性继承

有些属性可以继承,有些属性不能继承,如<code>color</code>可以继承,<code>width</code>就不能,具体哪些可以继承,哪些不能,一个简单方式记忆就是跟文字相关属性大都可以继承,跟布局相关属性大都继承

  • 常见的可继承属性:color,font(复合属性),letter-spacing,word-spacing...
  • 不可继承属性:display、margin、border、padding、background、height、min-height、max-height、width、min-width、max-width、overflow、position、left、right、top、bottom、z-index、float、clear、table-layout、vertical-align...

单一属性与复合属性

属性分为单一属性和复合属性,单一属性如 <code>color:red</code> ,复合属性如(以下三中表示等价):

padding: 10px 20px;
padding: 10px 20px 10px 20px;
padding-top:10px;
padding-right:20px;
padding-bottom:10px;
padding-left:20px;

CSS单位

尺寸单位

常见的尺寸单位有 <code>px</code>、<code>em</code>、<code>rem</code>、<code>%</code>、<code>pt</code>等等,初学者先记住<code>px</code>和<code>%</code>

颜色

常见颜色表示有以下几种:

  • 字符串表示如 <code>color:red</code>,顾名思义,红色
  • rgb表示如 <code>color:rgb(0,0,255)</code>,表示red:0, green:0, blue: 255,即纯蓝色
  • rgba表示如 <code>color:rgb(0,0,255, 0.5)</code>,比rgb多了一个appha值,即 0至1 的透明度
  • 16进制(HEX)表示如 <code>color:#ff0000</code>,如果每连续两个二进制相同,可以简写成一个,如果左边可以简写成<code>color:#f00</code>,字母不区分大小写
  • hsl颜色(不常用),如<code>color:hsl(120, 50%, 50%)</code>,
    • 说明:hsl是hue(色调)、saturation(饱和度)、lightness(亮度)首字母缩写,是颜色的另一表示
    • 取值:
      • hue为 0(红色)-360(红色),其实是色环的360度,当然也可以为380,其实与 20相同效果;
      • sturation为 0%(全灰)-100%(全彩);
      • lightness为 0%(黑色)-100%(白色);
  • hsla颜色(不常用),如<code>color:hsl(120, 50%, 50%, 0.5)</code>

关于颜色之间的转化可以进入 传送门


与布局相关的基本属性

  • display
  • width, height
  • max-width, max-height, min-width, min-height
  • padding, border, margin
  • float, overflow, clear
  • position, z-index, top, right, bottom, left

这些都是比较常用的属性,下面逐个做下介绍,如果你对 css盒模型 不了解的话推荐看下之前的一篇文章,传送门

第一组:display

用途

设置元素的显示属性,

取值

常见取值如下

none(隐藏), 常用于用户与页面交互时显示、隐藏元素,隐藏之后的元素,再设置别的属性都不会生效
inline(行内元素),设置width和height会被忽略, 会随正常文档流从左到右,从上到下布局
block(块元素),可以设置width, height
inline-block(行内块元素),兼有inline和block属性值的特点,既能设置width、height,也会随正常文档流左右布局

还有很多其他属性值,如 flextabletable-celltable-rowtable-column等,其中flex是css3新推出的属性,用法较多,本文暂不介绍。其他属性值使用相对较少

第二组: width, height

设置元素content宽度和高度。如果用百分比如<code>width: 30%</code>则表示为父容器content部分宽度的30%

第三组: max-width, max-height, min-width, min-height

设置元素最大、最小宽高,主要不同分辨率浏览器适配使用,经常媒体查询(@media)一起使用,如:

@media (max-width:1000px){
  body: 90%;
}

表示浏览器宽度小于或等于1000px时, body 宽度为父容器的 90%

第四组: padding, border, margin

设置元素的内边距、边框、外边距,这里需要理解盒模型,传送门,这里也不做解释了

第五组: float, clear, overflow

这一组与下一组是难点也是重点。

float属性

用于指定元素是否应该浮动或怎样浮动,取值如下:

none: 不浮动,也是所有元素的默认值,
left: 左浮动,值为left或right时,元素就脱离之前的文档流,其排版只受其他元素(也有float属性且非none的元素)影响。其兄弟元素或父元素如果没有float属性,就会当这个元素不存在,占其位置。所以一旦有了float属性就好像长了翅膀,飞起来后就不跟其他小伙伴玩了,其他小伙伴当然会占用ta之前的位置
right: 右浮动,同上

浮动元素有以下特点:

元素本身会塌陷:如果float之前没有设置width、height或为auto,则元素塌陷后的width、height为内部元素整体占的宽高,其本身会当作类似 inline-block 的元素影响周围元素

听起来有点绕,看下面代码

<!doctype html>
<html>
  <body>
    <div class='container'>
      <div class='sub-1'>
        <div class='sub-2'>sub-2</div>
      </div>
      <span class='text-1'>text-1</span>
    </div>
    <span class='text-2'>text-2</span>
  </body>
<html>
// 之前
.sub-1{}
.sub-2{height:10px;width:100px;}
// 之后
.sub-1{float:left;}
.sub-2{height:10px;width:100px;}

第一个样式显示的效果是,三行文本分三行显示,第二个样式显示效果是 sub-2text-1显示在了一行,而text-2显示在了第二行

第一个样式:显示三行应该不需要解释,sub-2被块元素 <code>.sub-1</code> 包裹,其他同理;.sub-1的与.sub-2相同,宽度为通栏
第二个样式:给 .sub-1 加入float后,其宽高都与.sub-2相同,并且是脱离文档流状态,类似与inline-block显示特性,所以text-1会在其后排版,因为.container没有脱离文档流,所以.text-2会换行显示

留下一个疑问:假如.sub-2高度为30px时会发生什么?欢迎互动

clear属性

清除浮动,主要将有 clear 属性且值为leftrightboth的元素在文档中以前的有浮动情况清除掉,使后面的文档不受float干扰,有以下取值

none:不清除浮动
left:清除左浮动
right:清除右浮动
both:清除左右浮动,比较常用

overflow属性

规定当容器内容溢出时如何显示,常见取值如下:

visible:溢出内容会显示
hidden:溢出内容会隐藏
scroll:无论内容是否溢出都会出现滚动条
auto:如果内容溢出会出现滚动条,不溢出则没有

第六组: position, z-index, top, right, bottom, left

这一组最难的一个属性是position,理解当前元素相对谁定位后,其对应的toprightbottomleft就很好理解了

position属性

CSS布局中,position几乎算是核心中的核心,因为你可以让人任意元素在浏览器的任何位置,也可以让元素影响正常文档流,也可以不影响正常文档流,而且还可以限定子元素定位的相对父亲,所以这么厉害的大招一定要学好,下面一个一个技能来学习,先看下取值:

  • absolute:绝对定位,一旦为此值,元素就会从直接父级容器开始找,如果父级元素有设置position属性,且不为static,则就把父级容器当作相对容器,然后停止继续向上查找,如果直接父级没有这个属性,则继续向上,找父级的父级元素,直到满足刚才的条件才停止查找,如果到最外层(html)都没有找到,则相对浏览器窗口,可见找爹的意志之坚定啊!
  • relative:相对定位,相对自身的位置,不会脱离文档流,如果同时设置了top:10px,此元素会离之前的位置向下移动 10px 距离,同时对除自身及内部元素以外的元素没有任何影响。
  • fixed:绝对定位,只相对浏览器窗口定位,配合toprightbottomleft可实现指哪定哪的特技
  • static:静态定位,所有元素的默认定位方式

z-index属性

用在设置有position属性,且值不为static的元素的显示层级,比如通过fixed定位的两个元素都在浏览器左上角,到底谁在上面,谁在下面?这个问题就只能交给z-index

取值为负整数、0、正整数,默认值为 -1

top, right, bottom, left

理解position定位后,找到相对元素,设置对应toprightbottomleft,注意定位 static的元素不会生效


文档流

个人觉得文档流通常有以下特点,可能不够准确

普通文档流就是 inlineinline-block 类型的元素从左到右、从上到下排版,相邻元素会互相影响,父元素会作为容器影响子元素
非普通文档流跟普通文档流对应,通常元素设置了positionfloat属性,使其尺寸大小及位置对兄弟元素不产生直接影响


<h1 style='text-align:center;margin-bottom:50px'>实战部分</h1>

这里仅列出比较常见的布局方式,还有很多其他方式等待你去实现

如果对布局不太熟悉的话,建议每个列子都亲自写一遍,加深记忆

两栏布局

左侧定宽,右侧自适应

方案一 float

.sidebar-rightmargin-right 也可以改成 padding-left

<!doctype html>
<html>
  <head>
    <style>
      .sidebar-left{
        width:100px;
        float:left;
      }
      .sidebar-right{
        margin-left:100px;
      }
      </style>
  </head>
  <body>
    <div class='container'>
      <div class='sidebar-left'>left</div>
      <div class='sidebar-right'>right</div>
    </div>
  </body>
<html>

方案二 position

一个 absolute,脱离文档流后,right元素只要设置个左边距即可

<!doctype html>
<html>
  <head>
    <style>
      .container{
        position:relative;
      }
      .sidebar-left{
        width:100px;
        position:absolute;
        left:0;
      }
      .sidebar-right{
        margin-left:100px;
      }
      </style>
  </head>
  <body>
    <div class='container'>
      <div class='sidebar-left'>left</div>
      <div class='sidebar-right'>right</div>
    </div>
  </body>
<html>

方案三 table-cell

这个例子中 .container 可以不设置,但是推荐写上,通常 table-cell 与父级 table 对应

<!doctype html>
<html>
  <head>
    <style>
      .container{
        width:100%;
        display:table;
      }
      .sidebar-left, .sidebar-right{
        display: table-cell;
      }
      .sidebar-left{
        width:100px;
      }
      </style>
  </head>
  <body>
    <div class='container'>
      <div class='sidebar-left'>left</div>
      <div class='sidebar-right'>right</div>
    </div>
  </body>
<html>

三栏布局

方案一 float

注意 .content 在DOM中的位置

<!doctype html>
<html>
  <head>
    <style>
      .sidebar-left{
        float:left;
        width:100px;
      }
      .content{
        margin:0 100px;
      }
      .sidebar-right{
        float:right;
        width:100px;
      }
      </style>
  </head>
  <body>
    <div class='container'>
      <div class='sidebar-left'>left</div>
      <div class='sidebar-right'>right</div>
      <div class='content'>content</div>
    </div>
  </body>
<html>

方案二 position

left及right元素设置了 absolute

<!doctype html>
<html>
  <head>
    <style>
      .container{
        position:relative;
      }
      .sidebar-left{
        position:absolute;
        left:0;
        width:100px;
      }
      .content{
        margin:0 100px;
      }
      .sidebar-right{
        position:absolute;
        right:0;
        width:100px;
      }
      </style>
  </head>
  <body>
    <div class='container'>
      <div class='sidebar-left'>left</div>
      <div class='content'>content</div>
      <div class='sidebar-right'>right</div>
    </div>
  </body>
<html>

方案三 table-cell

注意 .content 没有设置任何属性

<!doctype html>
<html>
  <head>
    <style>
      .container{
        width:100%;
        display:table;
      }
      .sidebar-left, .sidebar-right{
        display: table-cell;
        width:100px;
      }
      .sidebar-right{
        width:100px;
        display: table-cell;
      }
      </style>
  </head>
  <body>
    <div class='container'>
      <div class='sidebar-left'>left</div>
      <div class='content'>content</div>
      <div class='sidebar-right'>right</div>
    </div>
  </body>
<html>

定位布局

relative 相对定位

注意相对哪个元素定位

<!doctype html>
<html>
  <head>
    <style>
      .box-1,.box-3{
        background-color: #eee;
      }
      .box-2{
        width:300px;
        position: relative;
        top:-30px;
        left:130px;
        background-color: #aaa;
      }
      </style>
  </head>
  <body>
    <div class='container'>
      <div class='box-1'>
        轻轻的我走了, <br>
        正如我轻轻的来;<br> 
        我轻轻的招手, <br>
        作别西天的云彩。
      </div>
      <div class='box-2'>
        position:relative;<br>
        top: -30px;<br>
        left:130px
      </div>
      <div class='box-3'>
        那河畔的金柳,<br> 
        是夕阳中的新娘;<br> 
        波光里的艳影, <br>
        在我的心头荡漾。 
      </div>
    </div>
  </body>
<html>

absolute 绝对定位

注意相对的父元素是 .container 而非 body

<!doctype html>
<html>
  <head>
    <style>
      .container{
        position:relative;
        margin-left:200px;
      }
      .box-1,.box-3{
        background-color: #eee;
      }
      .box-2{
        width:300px;
        position: absolute;
        top:150px;
        left:30px;
        background-color: #aaa;
      }
      </style>
  </head>
  <body>
    <div class='container'>
      <div class='box-1'>
        轻轻的我走了, <br>
        正如我轻轻的来;<br> 
        我轻轻的招手, <br>
        作别西天的云彩。
      </div>
      <div class='box-2'>
        position:absolute;<br>
        top: 150px;<br>
        left: 30px
      </div>
      <div class='box-3'>
        那河畔的金柳,<br> 
        是夕阳中的新娘;<br> 
        波光里的艳影, <br>
        在我的心头荡漾。 
      </div>
    </div>
  </body>
<html>

fixed 绝对定位

上下滚动浏览器滚动条,观察灰色div位置

<!doctype html>
<html>
  <head>
    <style>
      .container{
        position:relative;
        margin-left:200px;
      }
      .box-1{
        height:1000px;
      }
      .box-2{
        width:300px;
        position: fixed;
        top:100px;
        left:50%;
        background-color: #eee;
      }
      </style>
  </head>
  <body>
    <div class='container'>
      <div class='box-1'>
        再别康桥 <br><br>
        作者: 徐志摩 <br><br>
        轻轻的我走了, <br>
        正如我轻轻的来; <br>
        我轻轻的招手, <br>
        作别西天的云彩。 <br>
          <br>
        那河畔的金柳, <br>
        是夕阳中的新娘; <br>
        波光里的艳影, <br>
        在我的心头荡漾。 <br>
          <br>
        软泥上的青荇, <br>
        油油的在水底招摇; <br>
        在康河的柔波里, <br>
        我甘心做一条水草! <br>
          <br>
        那榆荫下的一潭, <br>
        不是清泉, <br>
        是天上虹; <br>
        揉碎在浮藻间, <br>
        沉淀着彩虹似的梦。 <br>
          <br>
        寻梦?撑一支长篙, <br>
        向青草更青处漫溯; <br>
        满载一船星辉, <br>
        在星辉斑斓里放歌。 <br>
          <br>
        但我不能放歌, <br>
        悄悄是别离的笙箫; <br>
        夏虫也为我沉默, <br>
        沉默是今晚的康桥! <br>
          <br>
        悄悄的我走了, <br>
        正如我悄悄的来; <br>
        我挥一挥衣袖, <br>
        不带走一片云彩。
      </div>
      <div class='box-2'>
        position: fixed;<br>
        top:100px;<br>
        left:50%;
      </div>
    </div>
  </body>
<html>

响应式布局

max-width 最大宽

拖动浏览窗口,查看灰色背景div宽度变化

<!doctype html>
<html>
  <head>
    <style>
      .box-1{
        width:50%;
        max-width:400px;
        background-color:#ccc;
      }
      </style>
  </head>
  <body>
    <div class='container'>
      <div class='box-1'>
        轻轻的我走了, <br>
        正如我轻轻的来; <br>
        我轻轻的招手, <br>
        作别西天的云彩。 <br>
      </div>
    </div>
  </body>
<html>

media 媒体查询

常用语适配PC和移动端站点,拖动浏览器改变窗口大小试试,窗口小于 767px 时,观察 .box-1.box-2 的位置

<!doctype html>
<html>
  <head>
    <style>
      .box-1,.box-2{
        width:50%;
        float:left;
      }
      @media (max-width:767px){
        .box-1,.box-2{
          width:100%;
          float:none;
        }
      }
      </style>
  </head>
  <body>
    <div class='container'>
      <div class='box-1'>
        轻轻的我走了, <br>
        正如我轻轻的来; <br>
        我轻轻的招手, <br>
        作别西天的云彩。 
      </div>
      <div class='box-2'>
        那河畔的金柳, <br>
        是夕阳中的新娘; <br>
        波光里的艳影, <br>
        在我的心头荡漾。
      </div>
    </div>
  </body>
<html>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,703评论 1 92
  • 各种纯css图标 CSS3可以实现很多漂亮的图形,我收集了32种图形,在下面列出。直接用CSS3画出这些图形,要比...
    剑残阅读 9,349评论 0 8
  • 学习CSS的最佳网站没有之一 http://www.w3school.com.cn/tags/index.asp ...
    Amyyy_阅读 1,002评论 0 1
  • display:设置元素的显示方式 display:block(块级元素) 默认为父元素宽高,可设置宽高相对前序换...
    bluishwhiteC阅读 657评论 0 0
  • 一、文档流的概念指什么?有哪些方式可以让元素脱离文档流? 文档里指元素在文档中的位置由元素在html里的位置决定,...
    dengpan阅读 525评论 0 3