在限定盒子宽度的前提下.
<style>
.conatiner{}
.inner{
width:100px;
height:100px;
background:orange;
margin-left:auto;
margin-right:auto;
}
style>
<div class="container">
<div class="inner">div>
div>
块级元素, 如果不设置宽度, 再加上
margin
正值的话,margin
则会自动压缩盒子的宽;
常用于自适应布局, 两边始终保持左右的margin
值, 中间内容宽度根据屏幕宽度不同自适应
<style>
*{
margin:0;
padding:0;
}
.container{
background: pink;
height: 30px;
}
.inner{
height: 30px;
margin-left: 20px;
margin-right: 20px;
background: orange;
}
style>
<div class="container">
<div class="inner">div>
div>
<style>
* {
margin: 0;
padding: 0;
}
.container{
background:skyblue;
overflow: hidden;
}
ul {
float: left;
margin-left: 20px;
background: red;
}
li {
list-style: none;
width: 100px;
height: 100px;
background: pink;
border: 10px solid orange;
}
.merge-border li {
margin-bottom: -10px;
}
style>
<div class="container">
<ul>
<li>li>
<li>li>
ul>
<ul class="merge-border">
<li>li>
<li>li>
ul>
div>
比如四列, 想让左右两端对齐父容器两边界, 然后每个容器间的间距相等, 而且能够自适应屏幕宽度.
常规操作为, 子元素浮动布局, 靠左, 然后每个子元素添加margin-right
, 然后一排最后一个元素的margin-right
为 0 ;
利用负margin
, 则可以先拉长父容器的长度一个间距宽 , 然后再每个元素取 25% ( 4 列为例子 ) 排布 , 然后每个元素子内容, 不定宽度,margin-left
间距. 即可.
比如容器共宽 400px , 间距为20px , 则每一个元素宽应该为 (400-20*3) /4 = 85px 宽
现在先拉长 20px 宽, 容器宽为 420 px , 再平分4块, 每块为 105宽, 再内层margin-left
20px , 则每块为 105-20 = 85px , 而容器往左负的距离, 也被第一个元素的内层margin-left:20px
给拉回原位, 完美.
<style>
*{
margin:0;
padding:0;
}
.list{
margin-left: -18px;
margin-right: 0;
}
.list li{
width:25%;
height: 100px;
float:left;
list-style: none;
}
.list .inner{
height: 100px;
margin-left: 18px;
background: orange;
}
style>
<div class="container">
<ul class="list">
<li>
<div class="inner">div>
li>
<li>
<div class="inner">div>
li>
<li>
<div class="inner">div>
li>
<li>
<div class="inner">div>
li>
ul>
div>
这里最左边的一个元素 , 肯定是有一部分在可视区域范围之外的 , 也就是 间距宽的范围, 但是
inner
又margin-left
间距 , 则内容区域又回到可是范围.
1: 自适应
2: 改成其他列数方便, 如需要5列, 只需要设置li
的宽度为20%
;
3: 需改间距; 需修改list
的margin-left
的值和li .inner
的margin-left
值.
<style>
.container{
overflow:hidden;
}
.left{
width:100px;
float:left;
background:orange;
height: 300px;
}
.main{
margin:0 100px;
background:pink;
height: 80px;
}
.right{
width:100px;
float:right;
background:skyblue;
height: 300px;
}
.footer{
background: gray;
height: 30px;;
}
style>
<div class="container">
<div class="left">leftdiv>
<div class="right">rightdiv>
<div class="main">maindiv>
div>
<footer class="footer">footerfooter>
之所以可以实现的原理是:
left
和right
都是浮动元素,所以不占文档流空间,main 就直接从 container 0 0 的位置排布.
这里mian
的高度比两侧小的时候, 也能撑开container
的高度 , 而且这里的main
元素必须在left
和right
后面
效果如下:
考虑到优先渲染主要内容
main
区域内容, 所以main
放最前面 , 以下几种布局方式都能实现.
<style>
.container {
position: relative;
}
.left {
position: absolute;
left: 0;
top: 0;
width:100px;
background: orange;
height: 300px;
}
.main {
margin: 0 100px;
height: 80px;
background: pink;
}
.right {
position: absolute;
top: 0;
right: 0;
width:100px;
background: skyblue;
height: 300px;
}
.footer{
background: gray;
height: 30px;;
}
style>
<div class="container">
<div class="main">maindiv>
<div class="left">leftdiv>
<div class="right">rightdiv>
div>
<footer class="footer">footerfooter>
效果如下
可以看出, 虽然能够实现左中右三列布局 , 但是 left 和 right 是撑不开父容器 `container 的高度的
圣杯布局和双飞翼, 在于处理 main
的内容区域的处理方式不一样
主要利用 浮动布局 + 负的
margin
的使用.
优先main
标签 ,main
独占一行,left
和right
则会掉下来, 另起一行, 利用负的margin
, 将掉下来的left
和right
又挤到上一行, 也就是main
的上面.
注意:main
也必须是浮动布局,left
和right
的负 margin 才能挤上去.
step1 . 先实现分三列布局
<style>
.container{
overflow: hidden;
}
.main{
background: pink;
float:left;
width:100%;
height: 80px;
}
.left{
float: left;
width: 100px;
background: orange;
height: 300px;
margin-left: -100%;
}
.right{
float: left;
width:100px;
background: skyblue;
height: 300px;
margin-left: -100px;
}
.footer{
background: gray;
height: 30px;
}
style>
<div class="container">
<div class="main">maindiv>
<div class="left">leftdiv>
<div class="right">rightdiv>
div>
<footer class="footer">footerfooter>
效果如下:
可以看出, 分列是实现了, 但是main 的内容区域却与 left 和 right 重叠了
step2. 实现 main 的内容正常显示 ,也就是要空开 left 和 right 的位置.
核心是先将
container
左右各压缩left
和right
的宽度.main
100% 的宽度也就刚好, 是它本该的显示区域, 然后left
在上移后再往左移动自身宽度 ,right
在上移后往右移动自身宽度. 即可.
以下仅展示在 step1
后添加的内容:
<style>
.container{
padding:0 100px;
}
.left{
position:relative;
left:-100px;
}
.right{
position:relative;
right:-100px;
}
style>
或者利用 box-sizing
属性, padding 为设置的盒子( main
)宽度的一部分
.main{
box-sizing:border-box;
padding:0 100px;
}
双飞翼布局, 主要是在不兼容
box-sizing:border-box;
的兼容. 当不设置一个块级元素的宽度时 , 给该块级元素设置margin
, 就可以使得该块级元素根据父元素的宽度和 margin 定义自身宽度.
<style>
/* 其他的和 step1 的样式一致 */
.inner{
margin:0 100px;
}
<style>
<div class="container">
<div class="main">
<div class="inner">innerdiv>
div>
<div class="left">leftdiv>
<div class="right">rightdiv>
div>
<footer class="footer">footerfooter>
效果如下:
<style>
.container{
display:flex;
}
.left{
order:-1;
flex-basis:100px;
}
.main{
flex-grow:1;
}
.right{
flex-basis:100px;
}
style>
<div class="container">
<div class="main">maindiv>
<div class="left">leftdiv>
<div class="right">rightdiv>
div>