CSS整理

285 阅读13分钟

css总结

实现垂直居中的方式

基于表格定位

将要居中内容的外层容器元素的display设置成table,内层内容库使用table-cell,然后分别设置水平垂直居中

             /*表格方案*/
            #table-father{
                display:table;
            }
            #table-child{
                display:table-cell;
                text-align:center;
                vertical-align:middle;
            }

缺点是需要额外加标记

基于绝对定位

如果要居中的元素宽高已知并且不会更改,可以利用-margin,值是元素宽和高的一半

#child{
        position: absolute;
        left:50%;
        top:50%;
        margin-left:-50px;
        margin-top:-50px;
        width:100px;
        height:100px;
        background:gold;
  }

缺点是无法自适应,如果元素宽高是自适应百分比定义的,就不能用这种方法,因为margin采用百分比是相对于包含块的宽度而不是元素自身的宽度

如何解决元素自身宽高自适应的改变?

  1. translate()
#position-child{
                position:absolute;
                top:50%;
                left:50%;
                transform:translate(-50%,-50%);

translate基于自身宽度移动

  1. margin:auto
 .absolute-center {  
                  margin: auto;  
                  position: absolute;  
                  top: 0; left: 0; bottom: 0; right: 0;  
                  width:50%;
                  height:50%;
                } 

margin充满父元素

基于视口单位

要把元素相对于视口进行居中,那么相当于父元素的高度就是视口的高度,视口的高度可以用vh来获取:

 /*相对于视口单位进行居中的解决方案*/
            #view-child{
                margin:50vh auto 0;
                transform:translateY(-50%);
            }

基于 FlexBox

父元素设置为flex,子元素可以通过两种方式居中

/*基于伸缩盒的解决方案*/
            #flex-father{
                display:flex;

            }
            #flex-child{
                margin:auto;
            }
 div#flex-father{
                display:flex;
                align-items:center;
                justify-content: center;
            }

缺点是需要考虑浏览器支持

  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-flex;
  display: -ms-flexbox;
  display: flex;

Flex注意事项

  • Flex布局以后,子元素的float、clear和vertical-align属性将失效
  • flex内部的子元素(除了position:absolute或fixed)无论是display:block或者display:inline,都成为了伸缩项目
  • android浏览器4.4之前对于flex布局支持不好
  • flex-shrink属性用于设置或检索弹性盒的收缩比率,默认为1。不允许为负值,flex-shrink值为0时表示不收缩,保持自身
  • PC兼容性相对较差,IE要10,甚至11以上才有很好的兼容

盒子模型浅析

盒子模型的组成

盒子模型包含四个重要的部分: content(width、height):盒子内容宽高 padding:内边距(填充) border:边框 margin:外边距

重点:对于盒子来说,设置的宽高和真实占有宽高是不一样的

image

image

IE宽度是包括content,padding,border 标准宽度是只有content

CSS浮动

为什么要清除浮动

一个块级元素如果没有设置height,那么其高度就是由里面的子元素撑开,如果子元素使用浮动,脱离了标准的文档流,那么父元素的高度会将其忽略,如果不清除浮动,父元素会出现高度不够,那样如果设置border或者background都得不到正确的解析

在我们让元素浮动的时候,它就会离开原来的文档流,将它原先占有的空间释放。

打个比方,父元素就如一个有伸缩性的容器,而子元素就如一个气球。
当没有设置容器的高宽时,他的高宽完全是被装在里面的气球撑开的,当子元素浮动时候,就像气球从容器里飘了出来,飘在了他的上方。
而此时容器也就空了,由于伸缩性,高度就变为了o,看不见了。

清除浮动的方式

1.父元素添加高度

#div1{
            background-color: blank;
            height:200px;
        }

缺点:但当你调整子元素高度的时候,若你要实现父元素包含子元素的效果,你就也要调整父元素高度。

2.父元素也添加浮动

#div1{
            background-color: black;
            width: 100%;
            float: left;
        }

缺点:虽然可以解决问题,但是后面要添加有不需要浮动的子元素,则影响其显示

3.给父元素添加overflow:hidden;

#div1{
            background-color: black;
            overflow: hidden;
        }

缺点:一旦包含非浮动的子元素,则会影响其显示。

4.给父元素添加一个无关的元素,让添加的无关元素去清除浮动 clean:both;

        #div5{
            clear:both;
        }
    </style>
    <body>
        <div id="div1">
            <div id="div2"></div>
            <div id="div3"></div>
            <div id="div4"></div>
            <div id="div5"></div>
        </div>
    </body>

缺点:添加了一个无关元素,代码阅读受影响。

5.通过伪类来实现,在需要清除浮动的父元素里,添加一个清除浮动的伪类。

#div1:after{
            content: "";
            display: block;
            clear: both;
          }

实现两列布局的方法

首先创建基本的HTML布局和基本样式

<div class="wrapper" id="wrapper">
  <div class="left">
    左边固定宽度,高度不固定 </br> </br></br></br>高度有可能会很小,也可能很大。
  </div>
  <div class="right">
    这里的内容可能比左侧高,也可能比左侧低。宽度需要自适应。</br>
    基本的样式是,两个div相距20px, 左侧div宽 120px
  </div>
</div>
.wrapper {
    padding: 15px 20px;
    border: 1px dashed #ff6c60;
}
.left {
    width: 120px;
    border: 5px solid #ddd;
}
.right {
    margin-left: 20px;
    border: 5px solid #ddd;
}

双inline-block方案

.wrapper-inline-block {
    box-sizing: content-box;
    font-size: 0;	// 消除空格的影响
}

.wrapper-inline-block .left,
.wrapper-inline-block .right {
    display: inline-block;
    vertical-align: top;	// 顶端对齐
    font-size: 14px;
    box-sizing: border-box;
}

.wrapper-inline-block .right {
    width: calc(100% - 140px);
}

注:

  • 需要知道左侧盒子的宽度,两个盒子的距离,还要设置各个元素的box-sizing
  • 需要消除空格字符的影响
  • 需要设置vertical-align: top满足顶端对齐。

双float方案

.wrapper-double-float {
    overflow: auto;		// 清除浮动
    box-sizing: content-box;
}

.wrapper-double-float .left,
.wrapper-double-float .right {
    float: left;
    box-sizing: border-box;
}

.wrapper-double-float .right {
    width: calc(100% - 140px);
}

本方案和双float方案原理相同,都是通过动态计算宽度来实现自适应。但是,由于浮动的block元素在有空间的情况下会依次紧贴,排列在一行,所以无需设置display: inline-block;,自然也就少了顶端对齐,空格字符占空间等问题。

注:

  • 需要知道左侧盒子的宽度,两个盒子的距离,还要设置各个元素的box-sizing。
  • 父元素需要清除浮动。

float+margin-left方案

下面两种方案则是利用了block级别的元素盒子的宽度具有填满父容器,并随着父容器的宽度自适应的流动特性。 但是block级别的元素都是独占一行的,所以要想办法让两个block排列到一起。 我们知道,block级别的元素会认为浮动的元素不存在,但是inline级别的元素能识别到浮动的元素。这样,block级别的元素就可以和浮动的元素同处一行了。

.wrapper-float {
    overflow: hidden;		// 清除浮动
}

.wrapper-float .left {
    float: left;
}

.wrapper-float .right {
    margin-left: 150px;
}

缺点:

  • 需要清除浮动
  • 需要计算右侧盒子的margin-left

absolute+margin-left方案

另外一种让两个block排列到一起的方法是对左侧盒子使用position: absolute的绝对定位。这样,右侧盒子也能无视掉它

.wrapper-absolute .left {
    position: absolute;
}

.wrapper-absolute .right {
    margin-left: 150px;
}

缺点:

  • 使用了绝对定位,若是用在某个div中,需要更改父容器的position。
  • 没有清除浮动的方法,若左侧盒子高于右侧盒子,就会超出父容器的高度。因此只能通过设置父容器的min-height来放置这种情况。

float+BFC方案

这个方案同样是利用了左侧浮动,但是右侧盒子通过overflow: auto;形成了BFC,因此右侧盒子不会与浮动的元素重叠

.wrapper-float-bfc {
    overflow: auto;
}

.wrapper-float-bfc .left {
    float: left;
    margin-right: 20px;
}

.wrapper-float-bfc .right {
    margin-left: 0;
    overflow: auto;
}

这种情况下,只需要为左侧的浮动盒子设置margin-right,就可以实现两个盒子的距离了。而右侧盒子是block级别的,所以宽度能实现自适应。

flex方案

.wrapper-flex {
    display: flex;
    align-items: flex-start;
}

.wrapper-flex .left {
    flex: 0 0 auto;
}

.wrapper-flex .right {
    flex: 1 1 auto;
}

flex可以说是最好的方案了,代码少,使用简单。有朝一日,大家都改用现代浏览器,就可以使用了。 需要注意的是,flex容器的一个默认属性值:align-items: stretch;。这个属性导致了列等高的效果。 为了让两个盒子高度自动,需要设置: align-items: flex-start;

grid方案

.wrapper-grid {
    display: grid;
    grid-template-columns: 120px 1fr;
    align-items: start;
}

.wrapper-grid .left,
.wrapper-grid .right {
    box-sizing: border-box;
}

.wrapper-grid .left {
    grid-column: 1;
}

.wrapper-grid .right {
    grid-column: 2;
}

极限情况

最后可以再看一下在父容器极限小的情况下,不同方案的表现。主要分成四种情况:

  • 动态计算宽度的情况

两种方案: 双inline-block方案和双float方案。宽度极限小时,右侧的div宽度会非常小,由于遵循流动布局,所以右侧div会移动到下一行。

  • 动态计算右侧margin-left的情况

两种方案: float+margin-left方案和absolute+margin-left方案。宽度极限小时,由于右侧的div忽略了文档流中左侧div的存在,所以其依旧会存在于这一行,并被隐藏。

  • float+BFC方案的情况

这种情况下,由于BFC与float的特殊关系,右侧div在宽度减小到最小后,也会掉落到下一行。

  • flex和grid的情况

这种情况下,默认两种布局方式都不会放不下的div移动到下一行。不过 flex布局可以通过 flex-flow: wrap;来设置多余的div移动到下一行。 grid布局暂不支持。

单行居中两行居左

我们让内层 p 居左 text-align:left,外层 h2 居中 text-align:center,并且将 p 设置为display:inline-block ,利用 inline-block 元素可以被父级 text-align:center 居中的特性,这样就可以实现单行居中,多行居左,CSS 如下:

p {
    display: inline-block;
    text-align: left;
}
h2{
    text-align: center;
}

超出两行展示

display: -webkit-box; // 设置display,将对象作为弹性伸缩盒子模型显示
-webkit-line-clamp: 2; // 限制在一个块元素显示的文本的行数
-webkit-box-orient: vertical; // 规定框的子元素应该被水平或垂直排列

但是这样写后第一行也变回了居左,而没有居中,原因在于我们第一个设置的 display: inline-block ,被接下来设置的display: -webkit-box 给覆盖掉了,所以不再是 inline-block 特性的内部 p 元素占据了一整行,也就自然而然的不再居中,而变成了正常的居左展示

所以:

<h2><p><em>单行居中,多行居左<em></p></h2>

设置 em 为 display: -webkit-box
设置 p 为 inline-block
设置 h2 为 text-align: center

最终成果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        p{
            display:inline-block;   
            text-align:left;
        }
        em{
            display:-webkit-box;
            -webkit-line-clamp:2;
            -webkit-box-orient:vertical;
            overflow:hidden;
            text-overflow:ellipsis;
        }
        div{
            border: 1px solid red;
            font-size: 30px;
            text-align:center;
            width: 800px;
            height: 500px;
        }
    </style>
</head>
<body>
    <div>
        <p><em>单行居中,多行居左</em></p>
    </div>
</body>
</html>

如何制作一个三角形,梯形

    border-bottom: 50px solid red;
    width: 100px;
    border-left: 50px solid yellow;
    border-right: 50px solid green;
    border-top: 50px solid black;
    height: 0;
    width: 0;
    
    transparent //这个是透明

image

通过border 宽度和透明transparent 来实现三角形和梯形

渐变(Gradients)

线性渐变(Linear Gradient)

向下/向上/向左/向右/对角方向

#grad {
  background: -webkit-linear-gradient(180deg, red, blue); /* Safari 5.1 - 6.0 */
  background: -o-linear-gradient(180deg, red, blue); /* Opera 11.1 - 12.0 */
  background: -moz-linear-gradient(180deg, red, blue); /* Firefox 3.6 - 15 */
  background: linear-gradient(180deg, red, blue); /* 标准的语法 */
}

透明度
background: linear-gradient(to right, rgba(255,0,0,0), rgba(255,0,0,1)); /* 标准的语法 */

重复的线性渐变
background: repeating-linear-gradient(red, yellow 10%, green 20%);

径向渐变(Radial Gradients)

由它们的中心定义

#grad1 {
  /* Safari 5.1 - 6.0 */
  background: -webkit-radial-gradient(60% 55%, closest-side,blue,green,yellow,black); 
  /* Opera 11.6 - 12.0 */
  background: -o-radial-gradient(60% 55%, closest-side,blue,green,yellow,black);
  /* Firefox 3.6 - 15 */
  background: -moz-radial-gradient(60% 55%, closest-side,blue,green,yellow,black);
  /* 标准的语法 */
  background: radial-gradient(60% 55%, closest-side,blue,green,yellow,black);
}
 
#grad2 {
  /* Safari 5.1 - 6.0 */
  background: -webkit-radial-gradient(60% 55%, farthest-side,blue,green,yellow,black);
  /* Opera 11.6 - 12.0 */ 
  background: -o-radial-gradient(60% 55%, farthest-side,blue,green,yellow,black);
  /* Firefox 3.6 - 15 */
  background: -moz-radial-gradient(60% 55%, farthest-side,blue,green,yellow,black);
  /* 标准的语法 */
  background: radial-gradient(60% 55%, farthest-side,blue,green,yellow,black);
}

移动端适配

移动端适配个人接触的就那么几个

HTML的head部分

<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

其中:

width:viewport 的宽度,可以指定为一个像素值,如:640,或者为特殊的值,如:device-width (设备的宽度)。

initial-scale:初始缩放比例,即当浏览器第一次加载页面时的缩放比例。值为 1.0 即原始尺寸。

  maximum-scale:允许浏览者缩放到的最大比例,一般设为1.0,即原始尺寸。

  minimum-scale:允许浏览者缩放到的最小比例,一般设为1.0,即原始尺寸。

  user-scalable:浏览者是否可以手动缩放,yes 或 no 。   

px转为rem

页面 css 全部写完之后,将所有的 px 转换为以 rem 为单位的数字。例如 我设置 body 的 width :320px; 则根据 我在第三步设置的 font - size 值,转换为 rem ,则是

width :16 rem; 【320 / 20 (你设置的标准 font - size) = 16】

rem原理

什么是em

em作为font-size的单位时,其代表父元素的字体大小,em作为其他属性单位时,代表自身字体大小——MDN

  • em可以让我们的页面更灵活,更健壮,比起到处写死的px值,em似乎更有张力,改动父元素的字体大小,子元素会等比例变化,这一变化似乎预示了无限可能,有些人提出用em来做弹性布局页面
  • em做弹性布局的缺点还在于牵一发而动全身,一旦某个节点的字体大小发生变化

什么是rem

rem作用于非根元素时,相对于根元素字体大小;rem作用于根元素字体大小时,相对于其出初始字体大小——MDN

/* 作用于根元素,相对于原始大小(16px),所以html的font-size为32px*/
html{font-size:2rem}
/* 作用于非根元素,相对于根元素字体大小,所以为64px */
p{font-size:2rem}

em就是为字体和行高而生的,有些时候子元素字体就应该相对于父元素,元素行高就应该相对于字体大小;而rem的有点在于统一的参考系

Rem布局与案例

rem布局的本质基于宽度的等比缩放

比rem更好的方案

vw —— 视口宽度的 1/100;vh —— 视口高度的 1/100 —— MDN

仅用于个人整理,参考:

实现水平垂直居中的4种解决方案

Flex 布局教程:语法篇

七种实现左侧固定,右侧自适应两栏布局的方法

当子元素全部浮动时,怎么解决父元素塌陷的问题?

盒子模型浅析

谈谈一些有趣的CSS题目-- 单行居中,两行居左,超过两行省略

www.jianshu.com/p/09bd0ca51…