(第十天)CSS样式之盒子模型

盒子模型简介


所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用。
CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:margin,border,padding,和content。
盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。
下面的图片说明了盒子模型(Box Model):

来自runoob的盒子模型图

盒子类型的定义方式


盒子类型通过display属性进行定义。

常见的盒子类型
  • inline:内联型
  • block:块型
  • inline-block:具有块型部分属性的内联型
  • inline-table:可以让table具有inline的属性,即原table上下的元素可以排列在table的左右两侧
  • list-item:将元素设置为列表类型,具有block型元素的属性;该类型的元素可以使用li元素相关的属性,如list-style。

盒子的总宽与总高的计算方式


显式声明的宽度与高度

元素的总宽度计算公式是这样的:
总元素的宽度=设置的宽度+左填充+右填充+左边框+右边框+左边距+右边距
元素的总高度最终计算公式是这样的:
总元素的高度=设置的高度+顶部填充+底部填充+上边框+下边框+上边距+下边距

隐式(即没有设置)与显式的区别

显式声明的情况下,元素的总宽度总高度会随着margin、padding、border变化;
隐式声明的情况下,元素的内容宽度内容高度会随着margin、padding、border变化

代码示例
<head>
    <meta charset="UTF-8">
    <title>宽度与高度的显式与隐式</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        section {
            margin: 10px auto;
            border: 1px solid;
            width: 500px;
        }

        section div {
            margin: 10px;
            padding: 10px;
            background-color: #8A2BE2;
        }

        section p {
            margin: 10px;
            padding: 10px;
            background-color: #00ffcc;
        }

        section p span {
            margin: 10px;
            padding: 10px;
            background-color: #007F0E;
        }

        #explicit div {
            /*显式声明之后,margin、padding、border都会影响box的总宽度*/
            width: 500px;
        }

        #explicit span {
            /*inline元素,宽高无效;*/
            width: 500px;
            /*因为inline元素的宽高是由内容决定的,所以padding的多少不会影响正常的文档流
            所以就出现了超出父元素高度的效果.*/
            padding: 20px;
        }

    </style>
</head>
<body>
<section id="explicit">
    <h2>显式的宽高:section设置了width为500px</h2>
    <div>块级元素的父元素:显式宽度width:500px,总width=width+margin+border+padding,可超出父元素
        <p>隐式宽度,自适应父元素;块级元素的子元素<span>内联元素</span></p>
    </div>
</section>
</body>
上述代码效果图
box-sizing属性规定盒子的宽高计算方法
  • 属性值为content-box(默认值):width与height的属性值表示内容的宽高,padding、border都会改变盒子的总宽高
  • 属性值为border-box:width与height的属性值表示盒子总宽高,padding、border的设置不会改变盒子的总宽高,只会影响内容的宽高。

content-box和border-box属性值的区别就像隐式和显式设置宽高的区别一样,但是通过设置box-sizing:border-box,即使是显式设置height、width,padding、border的改变也不会影响盒子的总宽高。

<head>
    <meta charset="UTF-8">
    <title>设置盒子宽高针对的对象</title>
    <style>
        div{
            height:100px;
            width:100px;
        }
        .border_box{
            /*设置box-sizing为border-box,则该元素的width、height包含border,padding,content的宽度*/
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
            border:1em solid #ff0000;
            padding:1em;
            background-color: #ff0;
        }
        .content_box{
            /*设置box-sizing为content-box,则该元素的width、height只包含内容区域的width、height,
            增加border、padding属性会增加该元素的width、height*/
            -webkit-box-sizing: content-box;
            -moz-box-sizing: content-box;
            box-sizing: content-box;
            border: 1em solid #ff0000;
            padding: 1em;
            background-color: #ff0;
        }
    </style>
</head>
<body>
<h2>整个div宽高分别为100px*100px;内容区域width=div.width-border.width-padding.width</h2>
<div class="border_box">border-box</div>
<h2>内容区域width=div.width;若给div添加border、padding属性,则div.width会增加</h2>
<div class="content_box">content-box内容区域宽高分别为100px*100px</div>
</body>
上述代码示例的效果图

超出盒子范围的内容如何显示


通过overflow属性,可以设置当内容超出盒子宽高时的显式方式

overflow的属性值
  • hidden:超出盒子范围隐藏内容
  • scroll:出现超出盒子范围时,给盒子添加x,y轴上的滚动条;即使某方向上没有超出范围,也会出现灰条。
  • auto:根据内容x,y轴方向的超出情况,自动添加滚动条;若自有x轴超出,则只添加x轴滚动条;常见的情况只出现y轴方向滚动条,因为浏览器对元素的换行处理是超出盒子范围自动换行,若white-space设置为nowrap,那么超出盒子宽度则出现x轴方向的滚动条。
  • visible(默认):超出盒子范围的内容也正常显示
overflow的分开设置方式
  • overflow-x:宽度超出范围的处理方式
  • overflow-y:高度超出范围的处理方式
代码示例
<head>
    <meta charset="UTF-8">
    <title>超出盒子范围的内容如何显示?overflow</title>
    <style>
        *{
            margin:0px;
            padding:0px;
        }
        section{
            /*将section设置为内联块元素,并于不影响block元素的作用的同时同行显示*/
            display: inline-block;
        }
        h2{
            font-size:12px;
            margin: 5px 10px;
        }
        .box {
            height: 100px;
            width: 300px;
            background-color: red;
            margin-left: 10px;
        }
        #overflow_hidden{
            overflow: hidden;
        }
        #overflow_auto{
            /*因为浏览器默认会让超出范围的内容自动换行,故只有y轴出现滚动条*/
            overflow: auto;
        }
        #overflow_scroll{
            overflow: scroll;
        }
        #overflow_x{
            /*设置为不换行*/
            white-space: nowrap;
            overflow-x: scroll;
        }
        #overflow_y{
            overflow-y: scroll;
        }
    </style>
</head>
<body>
<section>
<h2>超出内容设置为隐藏,overflow:hidden</h2>
<div class="box" id="overflow_hidden">
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
</div>
</section>
<section>
<h2>根据内容情况自动设置scroll,overflow:auto</h2>
<div class="box" id="overflow_auto">
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
</div>
</section>
<section>
<h2>设置水平垂直方向都有滚动条,overflow:scroll</h2>
<div class="box" id="overflow_scroll">
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
</div>
</section>
<section>
<h2>单独设置水平方向为滚动,overflow-x:scroll</h2>
<div class="box" id="overflow_x">
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
</div>
</section>
<section>
<h2>单独设置垂直方向为滚动,overflow-y:scroll</h2>
<div class="box" id="overflow_y">
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
    这是盒子里的内容,是很长一段重复的话;
</div>
</section>
</body>
上述代码示例的效果图

外边距margin


常用属性
  • margin:上 右 下 左 下方属性的简写方式;省略其中一个值的情况下,省略的值对于对角的值,如省略最后的左,那么左的值会和右相等。
  • margin-top:上外边距
  • margin-right:右外边距
  • margin-bottom:下外边距
  • margin-left:左外边距
上下外边距的折叠
  1. 兄弟元素之间的margin合并
  • 现象:若上下两个元素都有margin属性,则会发生合并,合并后间距等于外边距较大的值;即上元素margin-bottom:10px; 下元素margin-top:20px; 那么上下元素之间的间距为20px,并非30px。
  • 解决:可以在不想被折叠的元素中添加display:inline-block属性值(ie7及以下会出现bug,但天猫都已经宣布放弃IE8了,那这里就不扯ie7的事了)或者float属性值防止兄弟元素之间的margin合并现象。
  1. 父子元素之间的margin合并
  • 现象:若父元素的第一个子元素或最后一个子元素分别有margin-top、margin-bottom属性,那么父元素的margin-top与第一个子元素的margin-top会出现合并现象,父元素的margin-bottom与最后一个子元素的margin-bottom也会出现合并现象。
  • 解决:
    1.子元素的margin-top改成padding-top,margin-bottom改成padding-bottom;
    2.给父元素折叠方向上添加对应的padding或者border属性值,大小不能为0;
    3.给父元素添加overflow:auto或者overflow:hidden的属性值同样可以解决
代码示例
<head>
    <meta charset="UTF-8">
    <title>margin的折叠问题</title>
    <style>
        * {
            padding: 0px;
            margin: 0px;
        }

        .parent {
            background-color: #ffff00;
        }

        .sub {
            margin: 10px;
            background-color: #00ffcc;
        }

        .none {
            /*inline-block元素设置的margin不会折叠,但元素变为内联元素,
            故width默认为实际内容的宽度,可自行设置width值*/
            display: inline-block;
            background-color: #8A2BE2;
        }
        .two{
            background-color: #8A2BE2;
        }
        .three {
            /*父元素设置border或者padding或者overflow都可以组织子元素与父元素的折叠*/
            /*border: 1px solid; 这种方式会增加盒子的宽高*/
            /*padding:1px; 这种方式同样会增加盒子的宽高*/
            overflow: auto; /*这种方式最理想,不会改变盒子的大小*/
        }
    </style>
</head>
<body>
<div class="parent">
    <div class="sub">第一个子元素,子元素与父元素的margin折叠; 子元素margin-top:10px 父元素margin-top:0px; 所以折叠后的上外边距为10px;</div>
    <div class="sub">第二个子元素,第一个子元素margin-bottom:10px; 该子元素margin-top:10px; 所以折叠后两元素的边距为10px</div>
    <div class="sub none">第三个子元素,如果元素中使用display:inline-block或者float,那么兄弟元素之间的上下margin不会折叠</div>
    <div class="sub">第四个子元素,第三个子元素设置了display:inline-block属性值,故两元素之间不会出现margin折叠;该元素的margin-bottom:10px与父元素的margin-bottom:0px折叠,故该元素与父元素之间没有外边距</div>
</div>
<div class="parent two">
    <div class="sub">第二个父元素的第一个子元素margin-top:10px与第一个父元素的最后一个子元素margin-bottom:10px折叠,故两个父元素之间的间距为10px</div>
</div>
<div class="parent three">
    <div class="sub">第三个父元素的第一个子元素margin-top:10px与第一个父元素的最后一个子元素margin-bottom:10px折叠,故两个父元素之间的间距为10px</div>
</div>

内边距padding


常用属性
  • padding:上 右 下 左 下方属性的简写方式;省略其中一个值的情况下,省略的值对于对角的值,如省略最后的左,那么左的值会和右相等。
  • padding-top:上内边距
  • padding-right:右内边距
  • padding-bottom:下内边距
  • padding-left:左内边距
利用padding与inline元素突破父元素的高度
#explicit span {
    /*inline元素,宽高无效;*/
    width: 500px;
    /*因为inline元素的宽高是由内容决定的,所以padding的多少不会影响正常的文档流;
    只要内容height+上下padding高于父元素height就出现了超出父元素高度的效果.*/
    padding: 20px;
}
墨绿背景的为子元素

边框border


border的四条边由四个倒梯形组成,若元素的总宽高由border决定时(即元素没有内容、没有padding、width与height都为0),那么border的四条边分别是四个倒三角形。


border的四条边

元素的width与height由border决定时的效果
常用属性
  • border-style:边框样式 如solid dotted等,是一种简写方式
    • border-top-style:上边框样式
    • border-right-style:右边框样式
    • border-bottom-style:下边框样式
    • border-left-style:左边框样式
  • border-width:边框的宽度,是一种简写方式
    • border-top-width:上边框宽度
    • border-right-width:右边框宽度
    • border-bottom-width:下边框宽度
    • border-left-width:左边框宽度
  • border-color:边框的颜色,是一种简写方式
    • border-top-color:上边框颜色
    • border-right-color:右边框颜色
    • border-bottom-color:下边框颜色
    • border-left-color:左边框颜色
代码示例
<head>
    <meta charset="UTF-8">
    <title>纯CSS画尖角</title>
    <style>
        * {
            margin: 0px;
            padding: 0px;
        }

        /*元素宽度和高度都为20px*/
        .test {
            width: 0;
            height: 0;
            border: 10px solid;
            /*border上右下左的颜色*/
            border-color: red yellow blue green;
        }

        .chat {
            margin-top: 10px;
            margin-left: 10px;
            position: relative;
        }

        .sharp {
            width: 0;
            height: 0;
            border: 10px solid;
            /*除了左边与聊天内容背景有相同的背景颜色外,其他颜色都为透明,造成一个三角的形状*/
            border-color: transparent #cceeff transparent transparent;
            position: absolute;
            left: -10px;
            top: 9px;
        }

        .content {
            background-color: #cceeff;
            padding: 10px;
            margin-left: 10px;
            width: 100px;
        }
    </style>
</head>
<body>
<div class="test"></div>
<div class="chat">
    <div class="sharp"></div>
    <div class="content">QQ聊天内容</div>
</div>
</body>
上述代码示例效果图
CSS3中引入的border属性,同样有上述中的top、right、bottom、left属性
  • border-radius:图像边框,数字值或%表示
  • box-shadow:边框阴影
    • h-shadow:必需。水平阴影的位置。允许负值。
    • v-shadow:必需。垂直阴影的位置。允许负值。
    • blur:可选。模糊距离。
    • spread:可选。阴影的尺寸。
    • color:可选。阴影的颜色。
    • inset:可选。将外部阴影 (outset) 改为内部阴影。
  • border-image:边框图片 后面有文章专门讲解
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容