css布局那点事

作者: 艾特TT | 来源:发表于2016-09-17 14:47 被阅读52次

    原文地址: 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>
    

    相关文章

      网友评论

        本文标题:css布局那点事

        本文链接:https://www.haomeiwen.com/subject/axfwettx.html