AboutFE icon indicating copy to clipboard operation
AboutFE copied to clipboard

12、布局类

Open CodingMeUp opened this issue 7 years ago • 8 comments

左边定宽、右边自适应(类似管理台)

  • 方案一 左边设置左浮动,右边宽度设置100% ()

.left {
  float: left;
}
.right {
  width: 100%
}
  • 方案二 左设置左浮动、右边也左浮动 但是使用calc去补宽度长度计算(方案一二没有完全分层)

.left {
  float: left;
}
.right {
  width: calc(100vw-200px);
}

-【分析】

  1. 浮动。(注意:为了不影响其他元素,别忘了在父级上清除浮动)
  2. calc() = calc(四则运算) 用于在 css 中动态计算长度值,需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
  3. vw: viewport width。1vw = viewport 宽度的 1%, 100vw = viewport width, 同样的还有 vh: viewport height。1vw = viewport 高度的 1%, 100vh = viewport height。 浏览器支持情况: 主流浏览器、IE10+ vw 和 vh 会随着viewport 的变化而变化,因此十分适合于自适应场景来使用。
  • 方案三 父容器设置 display:flex;right部分设置 flex:1

.contain {
  display: flex
}
.right {
  flex: 1
}
  • 方案四 右边div套个包裹、并前置、左及包裹 双浮动左

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<style media="screen">
.contain{
  background: pink;
  float: left;
  width: 100%;
}

.left{
  height: 200px;
  width: 200px;
  float: left;
  margin-left: -100%;
  background: red;
}

.right {
  background: blue;
  height: 300px;
  margin-left: 200px;
}

</style>
<body>
  <div class="contain">
    <div class="right">
      rrr
    </div>
   </div>
  <div class="left">lll </div>
</body>
</html>

【分析】

  1. 首先设置左边部分和右边部分左浮动,并为自适应部分(Right)设置宽度100%。此时的效果是这样的:
  2. 设置左边部分左外边距为负100%,此时效果如下: 但是右边部分的宽度仍然为100%,部分内容被 Left 所覆盖。
  3. 为 Right 部分添加左边距(即 Left 部分的宽度)

总结

关于左侧宽度固定,右侧宽度自适应两列布局的一种很常用的方法我相信大家都知道。就是利用左侧元素浮动,或者绝对定位的方式使其脱离常规文档流,让两个块级元素能够在同一行显示。然后右侧元素 margin-left 的值等于左侧元素宽度,这时右侧元素将紧挨着左侧元素,由于块元素的宽度会自动默认充满剩下的屏幕,所以就实现了右侧自适应的效果了。

第二种方法,我利用的是创建一个新的BFC(块级格式化上下文)来防止文字环绕的原理来实现的。BFC就是一个相对独立的布局环境,它内部元素的布局不受外面布局的影响。它可以通过以下任何一种方式来创建: float的值不为none position的值不为static或者relative display的值为 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一个 overflow的值不为visible   关于BFC,在w3c里是这样描述的:在BFC中,每个盒子的左外边框紧挨着包含块的左边框(从右到左的格式化时,则为右边框紧挨)。即使在浮动里也是这样的(尽管一个包含块的边框会因为浮动而萎缩),除非这个包含块的内部创建了一个新的BFC。

这样,当我们给右侧的元素单独创建一个BFC时,它将不会紧贴在包含块的左边框,而是紧贴在左元素的右边框。就像是箱子一个个排列 而不是叠上去

<!DOCTYPE>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="test.css" type="text/css">
</head>
<style media="screen">
.one {
  float: left;
  height: 100px;
  width: 300px;
  background-color: blue;
}
.two {
  overflow: auto;
  height: 200px;
  background-color: red;
}
</style>
<body>
    <div class="one"></div>
    <div class="two">第二种方法</div>
</body>
</html>

CodingMeUp avatar Nov 19 '17 14:11 CodingMeUp

水平居中

  • 行内元素的居中 (父元素 text-align: center ) 这样子元素如果为inline-block 就会居中
  • 块状元素居中 (块状没法用text-align)
    • 宽度一定: 我们使用对该元素margin: auto来实现 或 margin: 20px auto 并且一定要设置宽度值width 一起使用
    • 宽度不定 :
      1. 加table标签设置 margin:0 auto 将需要进行居中的元素,用一个大表格将其围起来(而且这个表格只有这一个单元格哦),然后设置表格的属性(如第2条方法)居中就行。不过缺点是加了不少的无用标签,代码看起来比较臃肿。
      2. display: inline 设置text-align:center 居中的块级元素的display属性设置为inline,这样的目的是先把块级元素变为行内元素,可以在一行内显示,然后将这些元素的父级元素text-align设置为:center即可。大概原理就是:块级->行内->居中(参照第1条方法),不过缺点也很明显,块级元素的一些特点没有了,例如高度、宽度设置等。
      3. 运用float属性,主要的思想也就是将所需要居中的元素先float到左边,这样就能在一行内显示,然后将整个列表float到父元素左边,然后设置left来设置居中。怎么设置呢?先设置父元素:left:50%,这样整个父元素就往右便宜50%,然后设置列表:right:50%,这样列表的东西再往左走父元素的50%,这样就达到了居中的目的 基本思想也就是将父元素(容器)先往右偏移父容器宽度的50%,然后再将列表的元素向左相对偏移50%,就可以得到居中的效果。

CodingMeUp avatar Nov 20 '17 03:11 CodingMeUp

垂直居中

  1. 固定高度
  • line-height + height 但是 固定高度,无法实现两行文本的垂直居中对齐
  • absolute 固定高度 无法自适应内容 元素脱离文档流
<div class="container">Hello World!</div>
.container {
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -150px;
    margin-top: -150px;
    width: 300px;
    height: 300px;
    border: 1px solid red;
}

// 支持calc 
.container {
    position: absolute;
    left: calc(50% - 150px);
    top: calc(50% - 150px);
    width: 300px;
    height: 300px;
    border: 1px solid red;
}
  • 空标签+float:left
<div class="space"></div>
<div class="container">
    <div class="inner">
        hello world!
    </div>
</div>

.space {
    float: left;
    height: 50%;
    margin-top: -150px;
}

.container {
    clear: both;
    height: 300px;
    border: 1px solid red;
    position: relative;
}
  1. 高度自适应
  • CSS3里使用transform里的translate()的两个百分比参数 如果两个参数都为百分比值,此时会基于自身宽度和高定进行移动。此函数移动的机制同position:relative相似
<div class="container">Hello World!</div>
.container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%); // 自身宽度和高度的一半
    border: 1px solid red;
}
优点:无需定高度。高度随内容自适应。
缺点:元素脱离文档流。如果需要居中的元素已经在高度上超过了视口,那它的顶部会被视口裁切掉。
  • 摆脱maigin 百分比靠父元素宽度的问题 50%加上translate负值并不能实现垂直居中布局。 改用 vh来做
<div class="container">Hello World!</div>

.container {
    width: 300px;
    margin: 50vh auto 0;
    transform: translateY(-50%);
    border: 1px solid red;
}
  • flex布局
<div class="container">
    <div class="inner">
        <p>hello world!</p>
    </div>
</div>

.container {
    display: flex;
    height: 100vh;
}

.inner {
    margin: auto;
}
当我们使父元素display: flex时,margin: auto不仅可以水平居中,也能够实现垂直居中。这是因为auto外边距会平分水平或垂直方向上的额外空间。
当然,也可以使用justify-content: center来定义弹性项目主轴的对齐方式,align-items: center来定义弹性项目侧轴的对齐方式。
.container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}
  • 模拟表格 父display:table 子display: table-cell vertical-align: middle
<div class="container">
    <div class="inner">
        hello world!
    </div>
</div>

.container {
    display: table;         /* 让div以表格的形式渲染 */
    width: 100%;
    border: 1px solid red;
}

.inner {
    display: table-cell;    /* 让子元素以表格的单元格形式渲染 */
    text-align: center;
    vertical-align: middle;
}

CodingMeUp avatar Nov 20 '17 03:11 CodingMeUp

左右定宽 中间自适应

  • position(绝对定位法) center的div需要放在最后面 绝对定位法原理是将左右两边使用absolute定位,因为绝对定位使其脱离文档流,后面的center会自然流动到他们上面,然后使用margin属性,留出左右元素的宽度,既可以使中间元素自适应屏幕宽度。
<div class='left'>left</div>
<div class='right'>right</div>
<div class='center'>center</div>
.left,.right{
    position: absolute;
    width: 200px;
    height: 200px;
    background-color: #df8793;
    top:0;
}
.left{
    left:0px;
}
.right{
    right: 0px;
}
.center{
    margin: 0 210px;
    overflow: hidden;
    background-color: yellow;
    height: 200px;
}
  • float:自身浮动法 center的div需要放在最后面 自身浮动法的原理就是使用对左右使用分别使用float:left和float:right,float使左右两个元素脱离文档流,中间元素正常在正常文档流中,使用margin指定左右外边距对其进行一个定位。
<div class='left'>left</div>
<div class='right'>right</div>
<div class='center'>center</div>
.left,.right{
    width: 200px;
    height: 200px;
    background-color: #df8793;
}
.left{
    float: left;
}
.right{
    float: right;
}
.center{
    margin: 0 210px;
    overflow: hidden;
    background-color: yellow;
    height: 200px;
}
  • 圣杯布局 圣杯布局的原理是margin负值法。使用圣杯布局首先需要在center元素外部包含一个div,包含div需要设置float属性使其形成一个BFC,并设置宽度,并且这个宽度要和left块的margin负值进行配合
<div class='wrap'>
    <div class='center'>center</div>
</div>
<div class='left'>left</div>
<div class='right'>right</div>

.wrap{
    width: 100%;    // .left  margin-left 同步
    float: left;
    height: 200px;
    background-color: #238978;
}
.center{
    margin: 0 210px;
}
.left{
    float: left;
    margin-left: -100%; // .wrap width同步
    width: 200px;
    height: 200px;
    background-color: #eee;
}
.right{
    float: left;
    margin-left: -200px;
    width: 200px;
    height: 200px;
    background-color: #eee;
}
  • flex布局 在外围包裹一层div,设置为display:flex;中间设置flex:1;但是盒模型默认紧紧挨着,可以使用margin控制外边距。
<div class='wrap'>
    <div class='left'>left</div>
    <div class='center'>center</div>
    <div class='right'>right</div>
</div>
.wrap{
    display: flex;
}
.center{
    flex:1;
    margin: 0 10px;
    background-color: pink;
}
.left{
    width: 200px;
    height: 200px;
    background-color: #eee;
}
.right{
    width: 200px;
    height: 200px;
    background-color: #eee;
}

CodingMeUp avatar Nov 27 '17 07:11 CodingMeUp

图片根据自己宽高自适应伸缩

使用场景:做图片预览的时候,根据图片真实的宽高比展示图片,又不想图片超出展示的范围

<div class="content">
 	<img src="./changzheng.png">
 </div>

.content {
	position: relative;
	width: 50%;
	height: 50%;
	border: 1px solid red;
	text-align: center;
	vertical-align: middle;
	font-size: 0;
	}
.content:after {
    display: inline-block;
    vertical-align: middle;
    width: 0;
    height: 100%;
    content: "";
	}

img {
	display: inline-block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
    vertical-align: middle;
}

CodingMeUp avatar Dec 12 '17 06:12 CodingMeUp

图片根据自己宽高自适应伸缩

使用场景:做图片预览的时候,根据图片真实的宽高比展示图片,又不想图片超出展示的范围

<div class="content">
 	<img src="./changzheng.png">
 </div>

.content {
	position: relative;
	width: 50%;
	height: 50%;
	border: 1px solid red;
	text-align: center;
	vertical-align: middle;
	font-size: 0;
	}
.content:after {
    display: inline-block;
    vertical-align: middle;
    width: 0;
    height: 100%;
    content: "";
	}

img {
	display: inline-block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
    vertical-align: middle;
}

CodingMeUp avatar Dec 12 '17 06:12 CodingMeUp

图片填充还有 position: absolute; left: 0; top: 0; right: 0; bottom: 0;

suedar avatar Dec 15 '17 01:12 suedar

:after content 加 font-size:0 的垂直居中打法堪称猥琐~

wsmPanda avatar Jan 03 '18 03:01 wsmPanda

更多布局类链接 https://juejin.im/post/5aa252ac518825558001d5de

CodingMeUp avatar May 20 '20 08:05 CodingMeUp