Skip to content

盒模型

本章将介绍CSS盒模型,这是理解CSS布局的基础。每个HTML元素都可以看作一个矩形盒子。

盒模型概述

CSS盒模型描述了元素如何占据空间,由四个部分组成:

+------------------------------------------+
|                  margin                  |  外边距
|  +------------------------------------+  |
|  |               border               |  |  边框
|  |  +------------------------------+  |  |
|  |  |           padding            |  |  |  内边距
|  |  |  +------------------------+  |  |  |
|  |  |  |                        |  |  |  |
|  |  |  |        content         |  |  |  |  内容区域
|  |  |  |                        |  |  |  |
|  |  |  +------------------------+  |  |  |
|  |  |                              |  |  |
|  |  +------------------------------+  |  |
|  |                                    |  |
|  +------------------------------------+  |
|                                          |
+------------------------------------------+

盒模型组成

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>盒模型组成示例</title>
    <style>
        .box {
            /* 内容区域 */
            width: 200px;              /* 内容宽度 */
            height: 100px;             /* 内容高度 */
            
            /* 内边距:内容到边框的距离 */
            padding: 20px;
            
            /* 边框 */
            border: 5px solid #333;
            
            /* 外边距:盒子到其他元素的距离 */
            margin: 30px;
            
            /* 背景色(显示内容区域和内边距) */
            background-color: #4CAF50;
        }
    </style>
</head>
<body>
    <div class="box">内容区域</div>
</body>
</html>

内容区域(Content)

内容区域是盒子的核心,用于显示元素的内容(文字、图片等)。

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>内容区域示例</title>
    <style>
        /* 设置内容区域的宽高 */
        .box {
            width: 300px;       /* 内容宽度 */
            height: 200px;      /* 内容高度 */
            background-color: #4CAF50;
            color: white;
            padding: 20px;
        }
        
        /* 使用min-width和max-width */
        .flexible {
            min-width: 200px;   /* 最小宽度 */
            max-width: 500px;   /* 最大宽度 */
            width: 100%;        /* 宽度百分比 */
            background-color: #2196F3;
        }
        
        /* 使用min-height和max-height */
        .flexible-height {
            min-height: 100px;  /* 最小高度 */
            max-height: 300px;  /* 最大高度 */
            height: auto;       /* 高度自适应 */
            overflow: auto;     /* 内容溢出时滚动 */
            background-color: #FF9800;
        }
    </style>
</head>
<body>
    <div class="box">固定尺寸盒子</div>
    <div class="flexible">弹性宽度盒子</div>
    <div class="flexible-height">
        <p>内容1</p>
        <p>内容2</p>
        <p>内容3</p>
    </div>
</body>
</html>

内边距(Padding)

内边距是内容区域与边框之间的空间。

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>内边距示例</title>
    <style>
        /* 无内边距 */
        .no-padding {
            background-color: #f5f5f5;
            border: 1px solid #333;
        }
        
        /* 有内边距 */
        .with-padding {
            padding: 20px;          /* 四边相同 */
            background-color: #f5f5f5;
            border: 1px solid #333;
        }
        
        /* 分别设置四边 */
        .padding-sides {
            padding-top: 10px;      /* 上 */
            padding-right: 20px;    /* 右 */
            padding-bottom: 30px;   /* 下 */
            padding-left: 40px;     /* 左 */
            background-color: #e8f5e9;
            border: 1px solid #4CAF50;
        }
        
        /* 简写形式 */
        .padding-shorthand {
            /* padding: 上 右 下 左; (顺时针) */
            padding: 10px 20px 30px 40px;
            background-color: #e3f2fd;
            border: 1px solid #2196F3;
        }
        
        /* 三个值:上 左右 下 */
        .padding-three {
            padding: 10px 20px 30px;
            background-color: #fff3e0;
            border: 1px solid #FF9800;
        }
        
        /* 两个值:上下 左右 */
        .padding-two {
            padding: 10px 20px;
            background-color: #fce4ec;
            border: 1px solid #E91E63;
        }
    </style>
</head>
<body>
    <div class="no-padding">无内边距</div>
    <br>
    <div class="with-padding">有内边距(20px)</div>
    <br>
    <div class="padding-sides">分别设置四边内边距</div>
    <br>
    <div class="padding-shorthand">简写形式:10px 20px 30px 40px</div>
    <br>
    <div class="padding-three">三个值:10px 20px 30px</div>
    <br>
    <div class="padding-two">两个值:10px 20px</div>
</body>
</html>

padding简写规则

css
/* 四个值:上 右 下 左(顺时针) */
padding: 10px 20px 30px 40px;

/* 三个值:上 左右 下 */
padding: 10px 20px 30px;

/* 两个值:上下 左右 */
padding: 10px 20px;

/* 一个值:四边相同 */
padding: 10px;

边框(Border)

边框围绕在内边距外面,是盒子的边界。

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>边框示例</title>
    <style>
        /* 基本边框 */
        .border-basic {
            border: 1px solid #333;  /* 宽度 样式 颜色 */
            padding: 10px;
            margin-bottom: 10px;
        }
        
        /* 不同样式 */
        .border-solid { border: 2px solid #333; }      /* 实线 */
        .border-dashed { border: 2px dashed #333; }    /* 虚线 */
        .border-dotted { border: 2px dotted #333; }    /* 点线 */
        .border-double { border: 4px double #333; }    /* 双线 */
        .border-groove { border: 4px groove #333; }    /* 3D凹槽 */
        .border-ridge { border: 4px ridge #333; }      /* 3D凸脊 */
        .border-inset { border: 4px inset #333; }      /* 3D内嵌 */
        .border-outset { border: 4px outset #333; }    /* 3D外凸 */
        
        /* 分别设置四边 */
        .border-sides {
            border-top: 3px solid red;
            border-right: 3px dashed green;
            border-bottom: 3px dotted blue;
            border-left: 3px double orange;
            padding: 10px;
            margin-bottom: 10px;
        }
        
        /* 边框宽度 */
        .border-width {
            border-style: solid;
            border-color: #333;
            border-width: 1px 5px 10px 15px;  /* 上 右 下 左 */
            padding: 10px;
            margin-bottom: 10px;
        }
        
        /* 边框颜色 */
        .border-color {
            border: 3px solid;
            border-color: red green blue orange;  /* 上 右 下 左 */
            padding: 10px;
            margin-bottom: 10px;
        }
        
        /* 无边框 */
        .no-border {
            border: none;
            background-color: #f5f5f5;
            padding: 10px;
        }
    </style>
</head>
<body>
    <div class="border-basic">基本边框</div>
    <div class="border-solid">实线边框</div>
    <div class="border-dashed">虚线边框</div>
    <div class="border-dotted">点线边框</div>
    <div class="border-double">双线边框</div>
    <div class="border-sides">四边不同样式</div>
    <div class="border-width">四边不同宽度</div>
    <div class="border-color">四边不同颜色</div>
    <div class="no-border">无边框</div>
</body>
</html>

圆角边框

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>圆角边框示例</title>
    <style>
        .box {
            width: 150px;
            height: 100px;
            background-color: #4CAF50;
            margin: 10px;
            display: inline-block;
            vertical-align: top;
        }
        
        /* 统一圆角 */
        .radius-1 {
            border-radius: 10px;  /* 四个角相同 */
        }
        
        /* 四个角分别设置 */
        .radius-2 {
            border-radius: 10px 20px 30px 40px;  /* 左上 右上 右下 左下 */
        }
        
        /* 椭圆圆角 */
        .radius-3 {
            border-radius: 20px / 10px;  /* 水平半径 / 垂直半径 */
        }
        
        /* 单独设置每个角 */
        .radius-4 {
            border-top-left-radius: 20px;
            border-top-right-radius: 40px;
            border-bottom-right-radius: 60px;
            border-bottom-left-radius: 80px;
        }
        
        /* 圆形 */
        .circle {
            width: 100px;
            height: 100px;
            border-radius: 50%;  /* 50%创建圆形 */
        }
        
        /* 椭圆 */
        .ellipse {
            border-radius: 50%;  /* 不同宽高创建椭圆 */
        }
        
        /* 胶囊形状 */
        .pill {
            border-radius: 50px;  /* 较大的圆角值 */
        }
    </style>
</head>
<body>
    <div class="box radius-1">统一圆角</div>
    <div class="box radius-2">四角不同</div>
    <div class="box radius-3">椭圆圆角</div>
    <div class="box radius-4">单独设置</div>
    <div class="box circle">圆形</div>
    <div class="box ellipse">椭圆</div>
    <div class="box pill">胶囊形状</div>
</body>
</html>

外边距(Margin)

外边距是盒子与其他元素之间的空间。

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>外边距示例</title>
    <style>
        .box {
            width: 100px;
            height: 100px;
            background-color: #4CAF50;
            display: inline-block;
            vertical-align: top;
        }
        
        /* 无外边距 */
        .no-margin {
            margin: 0;
        }
        
        /* 有外边距 */
        .with-margin {
            margin: 20px;  /* 四边相同 */
        }
        
        /* 分别设置四边 */
        .margin-sides {
            margin-top: 10px;
            margin-right: 20px;
            margin-bottom: 30px;
            margin-left: 40px;
        }
        
        /* 简写形式 */
        .margin-shorthand {
            /* margin: 上 右 下 左; */
            margin: 10px 20px 30px 40px;
        }
        
        /* 水平居中 */
        .center {
            margin: 0 auto;  /* 上下为0,左右自动 */
            display: block;
        }
        
        /* 负外边距 */
        .negative-margin {
            margin: -10px;
            background-color: #2196F3;
        }
    </style>
</head>
<body>
    <div class="box no-margin">无外边距</div>
    <div class="box no-margin">无外边距</div>
    
    <br><br>
    
    <div class="box with-margin">有外边距</div>
    <div class="box with-margin">有外边距</div>
    
    <br><br>
    
    <div class="box negative-margin">负外边距</div>
    <div class="box">普通盒子</div>
    
    <br><br>
    
    <div class="box center">水平居中</div>
</body>
</html>

外边距合并

垂直方向的外边距会发生合并:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>外边距合并示例</title>
    <style>
        .box {
            background-color: #4CAF50;
            padding: 10px;
        }
        
        /* 两个相邻元素的margin会合并 */
        .box1 {
            margin-bottom: 30px;
        }
        
        .box2 {
            margin-top: 20px;
            /* 实际间距是30px,不是50px */
        }
        
        /* 父子元素margin合并 */
        .parent {
            background-color: #f5f5f5;
            /* margin-top: 0;  解决方法1 */
            /* padding-top: 1px;  解决方法2 */
            /* overflow: hidden;  解决方法3 */
        }
        
        .child {
            margin-top: 30px;
            /* 如果父元素没有padding/border,margin会穿透到父元素外面 */
        }
    </style>
</head>
<body>
    <h3>相邻元素外边距合并</h3>
    <div class="box box1">盒子1(margin-bottom: 30px)</div>
    <div class="box box2">盒子2(margin-top: 20px)</div>
    <p>实际间距是30px(取较大值),不是50px</p>
    
    <h3>父子元素外边距合并</h3>
    <div class="parent">
        <div class="child">子元素(margin-top: 30px)</div>
    </div>
</body>
</html>

box-sizing属性

box-sizing属性决定了如何计算元素的总宽度和高度。

content-box(默认)

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>content-box示例</title>
    <style>
        /* 默认值:content-box */
        .content-box {
            box-sizing: content-box;  /* 默认值 */
            width: 200px;
            height: 100px;
            padding: 20px;
            border: 5px solid #333;
            margin: 10px;
            background-color: #4CAF50;
            
            /* 实际占用宽度 = 200 + 20*2 + 5*2 = 250px */
            /* 实际占用高度 = 100 + 20*2 + 5*2 = 150px */
        }
    </style>
</head>
<body>
    <div class="content-box">
        content-box模式<br>
        width: 200px<br>
        padding: 20px<br>
        border: 5px<br>
        实际宽度: 250px
    </div>
</body>
</html>

border-box(推荐)

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>border-box示例</title>
    <style>
        /* 推荐值:border-box */
        .border-box {
            box-sizing: border-box;
            width: 200px;
            height: 100px;
            padding: 20px;
            border: 5px solid #333;
            margin: 10px;
            background-color: #2196F3;
            
            /* 实际占用宽度 = 200px(包含padding和border) */
            /* 内容宽度 = 200 - 20*2 - 5*2 = 150px */
        }
        
        /* 全局设置border-box(推荐) */
        * {
            box-sizing: border-box;
        }
    </style>
</head>
<body>
    <div class="border-box">
        border-box模式<br>
        width: 200px<br>
        padding: 20px<br>
        border: 5px<br>
        实际宽度: 200px
    </div>
</body>
</html>

两种模式对比

属性content-boxborder-box
width/height只包含内容区域包含内容、内边距、边框
实际占用空间需要手动计算直接等于设置的宽高
使用场景特殊需求推荐日常使用

display属性

display属性决定元素的显示方式。

块级元素和行内元素

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>display属性示例</title>
    <style>
        /* 块级元素 */
        .block {
            display: block;
            width: 200px;
            height: 50px;
            background-color: #4CAF50;
            margin-bottom: 10px;
        }
        
        /* 行内元素 */
        .inline {
            display: inline;
            /* width和height无效 */
            width: 200px;      /* 无效 */
            height: 50px;      /* 无效 */
            background-color: #2196F3;
            padding: 10px;     /* 水平有效,垂直不影响布局 */
        }
        
        /* 行内块元素 */
        .inline-block {
            display: inline-block;
            width: 100px;
            height: 50px;
            background-color: #FF9800;
            margin: 5px;
        }
        
        /* 隐藏元素 */
        .none {
            display: none;  /* 完全隐藏,不占空间 */
        }
        
        .hidden {
            visibility: hidden;  /* 隐藏但占空间 */
        }
    </style>
</head>
<body>
    <h3>块级元素(block)</h3>
    <div class="block">块级元素1</div>
    <div class="block">块级元素2</div>
    
    <h3>行内元素(inline)</h3>
    <span class="inline">行内元素1</span>
    <span class="inline">行内元素2</span>
    
    <h3>行内块元素(inline-block)</h3>
    <div class="inline-block">行内块1</div>
    <div class="inline-block">行内块2</div>
    <div class="inline-block">行内块3</div>
</body>
</html>

元素类型对比

特性块级元素行内元素行内块元素
独占一行
设置宽高可以不可以可以
设置margin四边有效仅水平有效四边有效
设置padding四边有效仅水平有效四边有效
典型元素div、p、h1-h6、ulspan、a、strongimg、input

溢出处理

当内容超出盒子大小时,使用overflow属性处理:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>溢出处理示例</title>
    <style>
        .box {
            width: 200px;
            height: 100px;
            border: 1px solid #333;
            margin: 10px;
            display: inline-block;
            vertical-align: top;
        }
        
        /* 可见(默认) */
        .overflow-visible {
            overflow: visible;  /* 内容超出盒子显示 */
        }
        
        /* 隐藏 */
        .overflow-hidden {
            overflow: hidden;   /* 超出部分隐藏 */
        }
        
        /* 滚动 */
        .overflow-scroll {
            overflow: scroll;   /* 始终显示滚动条 */
        }
        
        /* 自动 */
        .overflow-auto {
            overflow: auto;     /* 内容超出时显示滚动条 */
        }
        
        /* 分别设置水平和垂直 */
        .overflow-xy {
            overflow-x: auto;   /* 水平方向自动 */
            overflow-y: hidden; /* 垂直方向隐藏 */
        }
        
        /* 文本溢出省略号 */
        .text-ellipsis {
            white-space: nowrap;      /* 不换行 */
            overflow: hidden;         /* 隐藏溢出 */
            text-overflow: ellipsis;  /* 显示省略号 */
        }
        
        /* 多行文本省略号 */
        .text-clamp {
            display: -webkit-box;
            -webkit-line-clamp: 3;    /* 显示3行 */
            -webkit-box-orient: vertical;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <h3>overflow: visible(默认)</h3>
    <div class="box overflow-visible">
        这是一段很长的文字内容,会超出盒子的边界显示出来。
        这是一段很长的文字内容,会超出盒子的边界显示出来。
    </div>
    
    <h3>overflow: hidden</h3>
    <div class="box overflow-hidden">
        这是一段很长的文字内容,超出部分会被隐藏。
        这是一段很长的文字内容,超出部分会被隐藏。
    </div>
    
    <h3>overflow: scroll</h3>
    <div class="box overflow-scroll">
        这是一段很长的文字内容,可以滚动查看。
        这是一段很长的文字内容,可以滚动查看。
        这是一段很长的文字内容,可以滚动查看。
    </div>
    
    <h3>overflow: auto</h3>
    <div class="box overflow-auto">
        这是一段很长的文字内容,超出时自动显示滚动条。
        这是一段很长的文字内容,超出时自动显示滚动条。
    </div>
    
    <h3>文本省略号</h3>
    <div class="box text-ellipsis">
        这是一段很长的文字内容,超出部分会显示省略号。
    </div>
    
    <h3>多行文本省略号</h3>
    <div class="box text-clamp">
        这是一段很长的文字内容,超出三行会显示省略号。
        这是一段很长的文字内容,超出三行会显示省略号。
        这是一段很长的文字内容,超出三行会显示省略号。
        这是一段很长的文字内容,超出三行会显示省略号。
    </div>
</body>
</html>

综合示例

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>盒模型综合示例</title>
    <style>
        /* 全局设置border-box */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Microsoft YaHei', Arial, sans-serif;
            background-color: #f5f5f5;
            padding: 20px;
        }
        
        /* 卡片容器 */
        .card {
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            margin-bottom: 20px;
            overflow: hidden;
        }
        
        /* 卡片头部 */
        .card-header {
            padding: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        
        /* 卡片内容 */
        .card-body {
            padding: 20px;
        }
        
        /* 盒模型演示 */
        .demo-box {
            width: 300px;
            padding: 20px;
            border: 5px solid #333;
            margin: 20px auto;
            background-color: #4CAF50;
            color: white;
            text-align: center;
        }
        
        /* 按钮样式 */
        .btn {
            display: inline-block;
            padding: 10px 20px;
            background-color: #667eea;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin: 5px;
        }
        
        .btn:hover {
            background-color: #5a6fd6;
        }
        
        /* 不同大小的按钮 */
        .btn-sm {
            padding: 5px 10px;
            font-size: 12px;
        }
        
        .btn-lg {
            padding: 15px 30px;
            font-size: 18px;
        }
        
        /* 图片卡片 */
        .image-card {
            width: 250px;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            display: inline-block;
            margin: 10px;
            vertical-align: top;
        }
        
        .image-card img {
            width: 100%;
            height: 150px;
            object-fit: cover;
            display: block;
        }
        
        .image-card .content {
            padding: 15px;
        }
        
        .image-card h3 {
            margin-bottom: 10px;
            font-size: 16px;
        }
        
        .image-card p {
            color: #666;
            font-size: 14px;
            line-height: 1.5;
        }
    </style>
</head>
<body>
    <div class="card">
        <div class="card-header">
            <h1>CSS盒模型</h1>
            <p>理解盒模型是掌握CSS布局的基础</p>
        </div>
        <div class="card-body">
            <h2>盒模型组成</h2>
            <p>每个HTML元素都可以看作一个矩形盒子,由内容(content)、内边距(padding)、边框(border)、外边距(margin)组成。</p>
            
            <div class="demo-box">
                内容区域<br>
                padding: 20px<br>
                border: 5px solid
            </div>
            
            <h2>按钮示例</h2>
            <button class="btn btn-sm">小按钮</button>
            <button class="btn">默认按钮</button>
            <button class="btn btn-lg">大按钮</button>
        </div>
    </div>
    
    <h2>图片卡片</h2>
    <div class="image-card">
        <img src="https://picsum.photos/300/200" alt="图片">
        <div class="content">
            <h3>卡片标题</h3>
            <p>这是卡片的描述内容,展示盒模型在实际项目中的应用。</p>
        </div>
    </div>
    
    <div class="image-card">
        <img src="https://picsum.photos/300/200?random=2" alt="图片">
        <div class="content">
            <h3>另一个卡片</h3>
            <p>通过合理设置padding和margin,可以创建美观的卡片布局。</p>
        </div>
    </div>
</body>
</html>

本章小结

本章我们学习了:

  1. 盒模型组成:content、padding、border、margin
  2. 内边距(padding):内容到边框的距离
  3. 边框(border):盒子的边界,可设置样式、宽度、颜色
  4. 外边距(margin):盒子与其他元素的距离
  5. box-sizing:content-box和border-box的区别
  6. display属性:block、inline、inline-block
  7. 溢出处理:overflow属性和文本省略号

下一章

下一章我们将学习 布局,掌握Flexbox和Grid布局技术。