盒模型与元素大小的计算
一、盒模型
- 用实例演示一下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>盒模型</title>
<style>
.box {
width: 200px;
height: 200px;
padding: 10px;
/* margin-left: auto;
margin-right: auto; */
background: brown;
background-clip: content-box;
border: 2px solid #000;
/* background-clip裁切 */
margin-bottom: 30px;
}
/*当两个盒子在垂直边距上时,外边距会产生折叠*/
.box1 {
background: coral;
width: 200px;
height: 200px;
padding: 10px;
border: 2px solid #000;
background-clip: content-box;
margin-top: 50px;
}
</style>
</head>
<body>
<div class="box"></div>
<div class="box1"></div>
</body>
</html>
- 上面代码的逻辑很简单,就是设两个宽200px,高200px的div,并设置2px的边框和10px的padding,30px的margin-bottom,50px的margin-top。然后我们来看效果:
- 这里我们会发现明明我们设置了200x200长宽比,为什么呈现出来的是一个224x224的盒子呢?
接着让我们打开调试页面一探究竟。
我们可以找到下面的这张示意图:
在这张图中,我们发现我们设置的200x200出现在了最里面的那个蓝框中,与此同时我们可以发现在这个盒模型中除了我们设置的内容(content),还有margin(外边距)、border(边框)、padding(内边框)
margin(外边距) - 清除边框外的区域,外边距是透明的。
border(边框) - 围绕在内边距和内容外的边框。
padding(内边距) - 清除内容周围的区域,内边距是透明的。
content(内容) - 盒子的内容,显示文本和图像。
由上图测试可知,元素的大小不是我们设置的200x200,而是加上了内边距和边框的大小:
224(width) = 200(content) + 10(padding)* 2 + 2(border)* 2
但是这样计算的话很不方便,所以我们可以用box-sizing: content-box|border-box|inherit;来更方便的设置元素大小
box-sizing: content-box;在自己设定的宽度和高度之外绘制元素的内边距和边框。
box-sizing: border-box;在自己设定的宽度和高度之内绘制元素的内边距和边框。
box-sizing: inherit;规定应从父元素继承 box-sizing 属性的值。
- 实例:
<style>
.box {
width: 200px;
height: 200px;
padding: 10px;
background: brown;
border: 2px solid #000;
box-sizing: border-box;
}
.box1 {
background: coral;
width: 200px;
height: 200px;
padding: 10px;
border: 2px solid #000;
box-sizing: content-box;
margin-top: 50px;
}
</style>
</head>
<body>
<div class="box"></div>
<div class="box1"><!-- <div class="box2"></div> --></div>
</body>
- 结果:
设置了box-sizing: border-box;属性元素的宽度就不会超过自己所设置的宽度大小;
设置了box-sizing: content-box;属性元素的宽度就会超过自己所设置的宽度大小;
当两个块级元素垂直排列时我们发现给第一个盒子设置的下边距30px和给第二个盒子设置的上边距50px并没有叠加起来,看下图就可以发现:
- 所以当两个盒子在垂直边距上时,外边距会产生折叠
二、元素的定位:
相对定位:以自己本身原来的位置为参照物进行偏移
position:relative;
实例:
<style>
.box1{width:400px;height:400px;border:1px solid #000;}
.box2{width:150px;height:150px;background:red;position:relative;left:100px;}
</style>
<body>
<div class="box1">
<div class="box2"></div>
</div>
</body>
绝对定位:相对于最近的且不是static定位的父元素来定位
position:absolute;
实例:
<style>
div {
width: 500px;
height: 100px;
}
.div1 {
background: yellow;
}
.div2 {
background: rgb(252, 28, 28);
}
.div3 {
background: rgb(14, 228, 25);
}
.div4 {
background: rgb(243, 24, 152);
left: 100px;
top: 100px;
}
</style>
<body>
<div class="div1">第一个div</div>
<div class="div2">第二个div</div>
<div class="div3">第三个div</div>
<div class="div4">第四个div</div>
</body>
显示结果:
Fixed:固定定位,是相对于浏览器窗口来定位的,是固定的,不会跟屏幕一起滚动。
position:fixed;
实例:设置div2为固定定位
.div2 {
background: rgb(252, 28, 28);
position: fixed;
left: 800px;
top: 0px;
}
- 显示结果:
- 元素的水平居中:设置元素margin-left:auto;margin-right:auto;
-实例:
<style>
.div1 {
width: 700px;
height: 500px;
background: red;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="div1"></div>
</body>
- 显示结果:
设置元素的左右外边距为auto,系统会自动调整左右间距相等,所以元素会居中显示
垂直居中:必须设置定位为绝对定位,并且设置上下左右为0,充满整个元素,可以理解为在方框内找中心点,把四个角用2条线连接起来,交点就是中点。
实例:
<style>
.box {
width: 800px;
height: 800px;
border: 2px solid #000;
position: relative;
}
.div1 {
width: 200px;
height: 200px;
background: rgb(251, 255, 0);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
</style>
</head>
<body>
<div class="box">
<div class="div1"></div>
</div>
</body>
- 显示结果:
- js获取元素的大小位置:
<style>
.box {
width: 200px;
height: 400px;
padding: 10px;
border: 2px solid #000;
background: lightskyblue;
background-clip: content-box;
}
.pos {
position: relative;
top: 30px;
left: 50px;
}
body {
margin: 0;
}
</style>
</head>
<body>
<div class="box pos"></div>
<script>
const box = document.querySelector(".box");
/* 获取div元素 */
/* 内容大小与位置 */
/* 大小 = width / height +padding */
console.log(box.clientWidth);
/* 获取元素的宽,不加内边距和边框 */
console.log(box.clientHeight);
/* 获取元素的高 ,不加内边距和边框*/
//clientLeft/clientTop:表示的是padding到border外边缘的距离:可以理解为边框宽度
//用的很少,了解一下
console.log(box.clientLeft);
console.log(box.clientTop);
console.log(document.documentElement.clientWidth);
//获取视口的宽度
console.log(document.documentElement.clientHeight);
//获取视口的长度
console.log(box.offsetParent);
//当前元素的定位偏移量,与定位有关
//定位父级
//这个元素现在是一个真正的盒子,包括了内容,内边距,边框
//真实宽度加上边框border
console.log(box.offsetWidth);
//元素真实的宽度,加内边距和边框
console.log(box.offsetHeight);
//元素真实的高度,加内边距和边框
console.log(box.offsetLeft);
//元素的左边间距
console.log(box.offsetTop);
//元素的顶部间距
const html = document.documentElement;
//获取当前的html元素
//当前文件的滚动大小
//视口大小:可视区大小
//文档大小:当前html的大小
//通常视口大小 < 文档大小,所以要通过滚动条来看到去拿不html文档的内容
html.style.height = "1000px";
//当前文档的高度
console.log(html.scrollHeight);
//当前可视区的高度
console.log(html.clientHeight);
//获取滚动条
console.log(html.scrollTop);
document.addEventListener("scroll", function (ev) {
console.log(html.scrollTop);
});
</script>
</body>
- 显示结果:
- 实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.box{
width:120px;
height:120px;
position:absolute;
top:50px;
left:10px;
}
.box img{
width:100%;
}
</style>
</head>
<body>
<div class="box">
<img src="走路.gif"></img>
</div>
<button>快跑</button>
<button>站住</button>
</body>
<script>
//只要不断改变图片在定位父级中的偏移量就可以实现
const thief = document.querySelector(".box");
//获取父级元素
const btn1 = document.querySelector("button:first-of-type");
const btn2 = document.querySelector("button:last-of-type");
//添加事件
btn1.addEventListener("click",start,{ once:true });
btn2.addEventListener("click",stop);
//定时器
let timer = null;
function start(){
console.log(thief.offsetLeft);
timer = setInterval(function(){
thief.style.left = thief.offsetLeft + 10 + "px";
thief.style.top = thief.offsetTop + 10 + "px";
},50);
}
function stop(){//清除定时器
clearInterval(timer);
}
</script>
</html>
- 显示结果:
三、学习总结
1. 盒模型:
content:内容在最中间
padding:内边距
border:边框
margin:外边距
box-sizing:content-box;只设定内容的宽度,高度
box-sizing:border-box;设定包括内容,内边距,边框的总宽度,总高度
垂直的块元素的间距会互相折叠
2.元素的大小位置
元素的真实的大小 = 内容(content) + 内边距(padding)x2 + 边框(border)x2
元素的定位:
position:relative; 相对定位:以自己本身原来的位置为参照物进行偏移
position: absolute; 绝对定位:相对于最近的且不是static定位的父元素来定位
position:fixed;固定定位:相对于浏览器窗口来定位的,是固定的,不会跟屏幕一起滚动。
- 元素的水平居中和垂直居中:
水平居中:marin:0 auto;/marin-left:auto;margin-right:auto;
垂直居中: 设置父元素的定位为绝对定位,然后设置上下左右间距为0,top=0;right:0;bottom=0;left=0;再设置上下居中,margin:auto;/margin-top:auto;margin-bottom:auto;
3.js获取元素大小位置
querySelector() 获取元素
box.clientWidth 获取元素的宽,只是content的宽度,不加内边距和边框
box.clientWidth 获取元素的高,只是content的高度,不加内边距和边框
document.documentElement.clientWidth 获取视口的宽度
document.documentElement.clientHeight 获取视口的高度
box.offsetParent 返回当前最近的经过定位的父级元素
box.offsetWidth 元素真实的宽度,加内边距和边框
box.offsetHeight 元素真实的高度,加内边距和边框
box.offsetLeft 元素的左边间距
box.offsetTop 元素的顶边间距
document.documentElement 获取html元素
html.style.height html文档高度 html.scrollHeight
html.clientHeight 当前可视区的高度
html.scrollTop 获取滚动条距离顶部的高度