CSS盒子模型
<style>.box {width: 200px;height: 100px;padding: 20px;}
</style>
<div class="box">盒子模型
</div>
<style>.box {width: 200px;height: 100px;padding: 20px;box-sizing: border-box;}
</style>
<div class="box">盒子模型
</div>
这时候你就可以发现 盒子所占的宽度为200px;
如何实现两栏布局右侧自适应和三栏布局中间自适应
<style>.box{overflow: hidden; BFC}.left {float: left;width: 200px;background-color: gray;height: 400px;}.right {margin-left: 210px;background-color: lightgray;height: 200px;}
</style>
<div class="box"><div class="left"> </div><div class="right"> </div>
</div>
Flex弹性盒子布局
<style>.box{display: flex;}.left {width: 100px;}.right {flex: 1;}
</style>
<div class="box"><div class="left"> Left</div><div class="right"> Right </div>
</div>
三栏布局
<style>.wrap {background: #eee;overflow: hidden; <!-- 生成BFC,计算高度时考虑浮动的元素 -->padding: 20px;height: 200px;}.left {width: 200px;height: 200px;float: left;background: coral;}.right {width: 120px;height: 200px;float: right;background: lightblue;}.middle {margin-left: 220px;height: 200px;background: lightpink;margin-right: 140px;}
</style>
<div class="wrap"><div class="left">左侧</div><div class="right">右侧</div><div class="middle">中间</div>
</div>
原理如下:
- 两边固定宽度,中间宽度自适应。
- 利用中间元素的margin值控制两边的间距
- 宽度小于左右部分宽度之和时,右侧部分会被挤下去
- 这种实现方式存在缺陷:
- 主体内容是最后加载的。
- 右边在主体内容之前,如果是响应式设计,不能简单的换行展示
两边使用 absolute,中间使用 margin
基于绝对定位的三栏布局:注意绝对定位的元素脱离文档流,相对于最近的已经定位的祖先元素进行定位。无需考虑HTML中结构的顺序。
<style>.container {position: relative;}.left,.right,.main {height: 200px;line-height: 200px;text-align: center;}
.left {position: absolute;top: 0;left: 0;width: 100px;background: green;}
.right {position: absolute;top: 0;right: 0;width: 100px;background: green;}
.main {margin: 0 110px;background: black;color: white;}
</style>
<div class="container"><div class="left">左边固定宽度</div><div class="right">右边固定宽度</div><div class="main">中间自适应</div>
</div>
实现流程:
- 左右两边使用绝对定位,固定在两侧。
- 中间占满一行,但通过 margin和左右两边留出10px的间隔
两边使用 float 和负 margin。
<style>.left,.right,.main {height: 200px;line-height: 200px;text-align: center;}
.main-wrapper {float: left;width: 100%;}
.main {margin: 0 110px;background: black;color: white;}
.left,.right {float: left;width: 100px;margin-left: -100%;background: green;}
.right {margin-left: -100px; /* 同自身宽度 */}
</style>
<div class="main-wrapper"><div class="main">中间自适应</div>
</div>
<div class="left">左边固定宽度</div>
<div class="right">右边固定宽度</div>
实现过程:
- 中间使用了双层标签,外层是浮动的,以便左中右能在同一行展示
- 左边通过使用负 margin-left:-100%,相当于中间的宽度,所以向上偏移到左侧
- 右边通过使用负 margin-left:-100px,相当于自身宽度,所以向上偏移到最右侧
缺点:
- 增加了 .main-wrapper 一层,结构变复杂
- 使用负 margin,调试也相对麻烦
使用 display: table 实现
<style>.container {height: 200px;line-height: 200px;text-align: center;display: table;table-layout: fixed;width: 100%;}
.left,.right,.main {display: table-cell;}
.left,.right {width: 100px;background: green;}
.main {background: black;color: white;width: 100%;}
</style>
<div class="container"><div class="left">左边固定宽度</div><div class="main">中间自适应</div><div class="right">右边固定宽度</div>
</div>
实现原理:
- 层通过 display: table设置为表格,设置 table-layout: fixed`表示列宽自身宽度决定,而不是自动计算。
- 内层的左中右通过 display: table-cell设置为表格单元。
- 左右设置固定宽度,中间设置 width: 100% 填充剩下的宽度
使用flex实现
利用flex弹性布局,可以简单实现中间自适应
代码如下:
<style type="text/css">.wrap {display: flex;justify-content: space-between;}
.left,.right,.middle {height: 100px;}
.left {width: 200px;background: coral;}
.right {width: 120px;background: lightblue;}
.middle {background: #555;width: 100%;margin: 0 20px;}
</style>
<div class="wrap"><div class="left">左侧</div><div class="middle">中间</div><div class="right">右侧</div>
</div>
实现过程:
- 仅需将容器设置为display:flex;,
- 盒内元素两端对其,将中间元素设置为100%宽度,或者设为flex:1,即可填充空白
- 盒内元素的高度撑开容器的高度
优点:
- 结构简单直观
- 可以结合 flex的其他功能实现更多效果,例如使用 order属性调整显示顺序,让主体内容优先加载,但展示在中间
grid网格布局
代码如下:
<style>.wrap {display: grid;width: 100%;grid-template-columns: 300px auto 300px;}
.left,.right,.middle {height: 100px;}
.left {background: coral;}
.right {width: 300px;background: lightblue;}
.middle {background: #555;}
</style>
<div class="wrap"><div class="left">左侧</div><div class="middle">中间</div><div class="right">右侧</div>
</div>
CSS中,有哪些方式可以隐藏页面元素?有什么区别?
一、前言
在平常的样式排版中,我们经常遇到将某个模块隐藏的场景
通过css隐藏元素的方法有很多种,它们看起来实现的效果是一致的
但实际上每一种方法都有一丝轻微的不同,这些不同决定了在一些特定场合下使用哪一种方法
二、实现方式
通过css实现隐藏元素方法有如下:
display:none
visibility:hidden
opacity:0
设置height、width模型属性为0
position:absolute
clip-path
display:none
设置元素的display为none是最常用的隐藏元素的方法:
.hide {display:none;
}
将元素设置为display:none后,元素在页面上将彻底消失
元素本身占有的空间就会被其他元素占有,也就是说它会导致浏览器的重排和重绘
消失后,自身绑定的事件不会触发,也不会有过渡效果
特点:元素不可见,不占据空间,无法响应点击事件
visibility:hidden
设置元素的visibility为hidden也是一种常用的隐藏元素的方法
从页面上仅仅是隐藏该元素,DOM结果均会存在,只是当时在一个不可见的状态,不会触发重排,但是会触发重绘;
.hidden{visibility:hidden
}
给人的效果是隐藏了,所以他自身的事件不会触发
特点:元素不可见,占据页面空间,无法响应点击事件
opacity:0
opacity属性表示元素的透明度,将元素的透明度设置为0后,在我们用户眼中,元素也是隐藏的
不会引发重排,一般情况下也会引发重绘
如果利用 animation 动画,对 opacity 做变化(animation会默认触发GPU加速),则只会触发 GPU 层面的 composite,不会触发重绘
.transparent {opacity:0;
}
由于其仍然是存在于页面上的,所以他自身的的事件仍然是可以触发的,但被他遮挡的元素是不能触发其事件的
需要注意的是:其子元素不能设置opacity来达到显示的效果
特点:改变元素透明度,元素不可见,占据页面空间,可以响应点击事件
设置height、width属性为0
将元素的margin,border,padding,height和width等影响元素盒模型的属性设置成0,如果元素内有子元素或内容,还应该设置其overflow:hidden来隐藏其子元素
.hiddenBox {margin:0; border:0;padding:0;height:0;width:0;overflow:hidden;
}
特点:元素不可见,不占据页面空间,无法响应点击事件
position:absolute
将元素移出可视区域
.hide {position: absolute;top: -9999px;left: -9999px;
}
特点:元素不可见,不影响页面布局
clip-path
通过裁剪的形式
.hide {clip-path: polygon(0px 0px,0px 0px,0px 0px,0px 0px);
}
特点:元素不可见,占据页面空间,无法响应点击事件
小结
最常用的还是display:none和visibility:hidden,其他的方式只能认为是奇招,它们的真正用途并不是用于隐藏元素,所以并不推荐使用它们.
行内元素和块级元素有什么区别
行内元素(Inline Elements):
-
默认情况下,行内元素在水平方向上以行内的方式显示,不会独占一行。
-
行内元素只能容纳文本或其他行内元素,不能容纳块级元素。
-
行内元素的宽度和高度由其内容决定,无法设置固定的宽度和高度。
-
行内元素可以设置左右的外边距(margin)和内边距(padding),但上下外边距和内边距对行内元素不起作用。
常见的行内元素包括
等。
块级元素(Block-level Elements):
-
默认情况下,块级元素会独占一行的空间,即使它们宽度没有填满父元素的水平空间。
-
块级元素可以包含其他块级元素和行内元素。
-
块级元素的宽度、高度、内外边距都可以通过 CSS 设置。
-
块级元素会自动在其前后创建换行。
常见的块级元素包括
等。
通过 CSS 的 display 属性可以修改元素的显示方式,例如将行内元素设置为块级元素或将块级元素设置为行内元素,这样可以改变元素在页面中的布局和显示效果。
em/px/rem/vh/vw 这些单位有什么区别?
一、介绍
传统的项目开发中,我们只会用到px、%、em这几个单位,它可以适用于大部分的项目开发,且拥有比较良好的兼容性
从CSS3开始,浏览器对计量单位的支持又提升到了另外一个境界,新增了rem、vh、vw、vm等一些新的计量单位
利用这些新的单位开发出比较良好的响应式页面,适应多种不同分辨率的终端,包括移动设备等
二、单位
在css单位中,可以分为长度单位、绝对单位,如下表所指示
这里我们主要讲述px、em、rem、vh、vw
px
px,表示像素,所谓像素就是呈现在我们显示器上的一个个小点,每个像素点都是大小等同的,所以像素为计量单位被分在了绝对长度单位中
有些人会把px认为是相对长度,原因在于在移动端中存在设备像素比,px实际显示的大小是不确定
这里之所以认为px为绝对单位,在于px的大小和元素的其他属性无关
em
em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸(1em = 16px)
为了简化 font-size 的换算,我们需要在css中的 body 选择器中声明font-size= 62.5%,这就使 em 值变为 16px*62.5% = 10px
这样 12px = 1.2em, 10px = 1em, 也就是说只需要将你的原来的 px 数值除以 10,然后换上 em 作为单位就行了
特点:
-
em 的值并不是固定的
-
em 会继承父级元素的字体大小
-
em 是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸
-
任意浏览器的默认字体高都是 16px
<style>
html {font-size: 10px; } /* 公式16px*62.5%=10px */
.big{font-size: 1.4em}
.small{font-size: 1.2em}
</style>
<div class="big">我是14px=1.4em<div class="small">我是12px=1.2em</div>
</div>
这时候.big元素的font-size为14px,而.small元素的font-size为12px
rem
rem,相对单位,相对的只是HTML根元素font-size的值
同理,如果想要简化font-size的转化,我们可以在根元素html中加入font-size: 62.5%
html {font-size: 62.5%; } /* 公式16px*62.5%=10px */
这样页面中1rem=10px、1.2rem=12px、1.4rem=14px、1.6rem=16px;使得视觉、使用、书写都得到了极大的帮助
特点:
rem单位可谓集相对大小和绝对大小的优点于一身
和em不同的是rem总是相对于根元素,而不像em一样使用级联的方式来计算尺寸
vh、vw
vw ,就是根据窗口的宽度,分成100等份,100vw就表示满宽,50vw就表示一半宽。(vw 始终是针对窗口的宽),同理,vh则为窗口的高度
这里的窗口分成几种情况:
- 在桌面端,指的是浏览器的可视区域
- 移动端指的就是布局视口
像vw、vh,比较容易混淆的一个单位是%,不过百分比宽泛的讲是相对于父元素: - 对于普通定位元素就是我们理解的父元素
- 对于position: absolute;的元素是相对于已定位的父元素
- 对于position: fixed;的元素是相对于 ViewPort(可视窗口)
三、总结
px:绝对单位,页面按精确像素展示
em:相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算,整个页面内1em不是一个固定的值
rem:相对单位,可理解为root em, 相对根节点html的字体大小来计算
vh、vw:主要用于页面视口大小布局,在页面布局上更加方便简单
HTML和CSS图片的加载规则
Web浏览器先会把获取到的HTML代码解析成一个DOM树,HTML中的每个标签都是DOM树中的一个节点,包括display: none隐藏的标签,还有JavaScript动态添加的元素等。
浏览器会获取到所有样式,并会把所有样式解析成样式规则,在解析的过程中会去掉浏览器不能识别的样式。
浏览器将会把DOM树和样式规则组合在一起(DOM元素和样式规则匹配)后将会合建一个渲染树(Render Tree),渲染树类似于DOM树,但两者别还是很大的:
渲染树能识别样式,渲染树中每个节点(NODE)都有自己的样式,而且渲染树不包含隐藏的节点(比如display:none的节点,还有内的一些节点),因为这些节点不会用于渲染,也不会影响节点的渲染,因此不会包含到渲染树中。一旦渲染树构建完毕后,浏览器就可以根据渲染树来绘制页面了。
简单的归纳就是浏览器渲染Web页面大约会经过六个过程:
- 解析HTML,构成DOM树
- 解析加载的样式,构建样式规则树
- 加载JavaScript,执行JavaScript代码
- DOM树和样式规则树进行匹配,构成渲染树
- 计算元素位置进行页面布局
- 绘制页面,最终在浏览器中呈现
是不是会感觉这个和我们图像加载渲染没啥关系一样,事实并非如此,因为img、picture或者background-image都是DOM树或样式规则中的一部分,那么咱们套用进来,图片加载和渲染的时机有可能是下面这样: - 解析HTML时,如果遇到img或picture标签,将会加载图片
- 解析加载的样式,遇到background-image时,并不会加载图片,而会构建样式规则树
- 加载JavaScript,执行JavaScript代码,如果代码中有创建img元素之类,会添加到DOM树中;如查有添加background-image规则,将会添加到样式规则树中
- DOM树和样式规则匹配时构建渲染树,如果DOM树节点匹配到样式规则中的backgorund-image,则会加载背景图片
- 计算元素(图片)位置进行布局
- 开始渲染图片,浏览器将呈现渲染出来的图片
上面套用浏览器渲染页面的机制,但图片加载与渲染还是有一定的规则。因为,页面中不是所有的(或picture)元素引入的图片和background-image引入的背景图片都会加载的。那么就引发出新问题了,什么时候会真正的加载,加载规则又是什么?
先概括一点:
Web页面中不是所有的图片都会加载和渲染!
我们可以归纳为: - image picture和设置background-image的元素遇到display:none时,图片会加载,但不会渲染。
- image picture和设置background-image的元素祖先元素设置display:none时,background-image不会渲染也不会加载,而img和picture引入的图片不会渲染但会加载
- image picture和background-image引入相同路径相同图片文件名时,图片只会加载一次
- 样式文件中background-image引入的图片,如果匹配不到DOM元素,图片不会加载
- 伪类引入的background-image,比如:hover,只有当伪类被触发时,图片才会加载.
什么是响应式设计?响应式设计的基本原理是什么?如何进行实现?
一、是什么
响应式网站设计(Responsive Web design)是一种网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整
描述响应式界面最著名的一句话就是“Content is like water”
大白话便是“如果将屏幕看作容器,那么内容就像水一样”
响应式网站常见特点:
同时适配PC + 平板 + 手机等
标签导航在接近手持终端设备时改变为经典的抽屉式导航
网站的布局会根据视口来调整模块的大小和位置
二、实现方式
响应式设计的基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端,页面头部必须有meta声明viewport
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no”>
属性对应如下:
- width=device-width: 是自适应手机屏幕的尺寸宽度
- maximum-scale:是缩放比例的最大值
- inital-scale:是缩放的初始化
- user-scalable:是用户的可以缩放的操作
实现响应式布局的方式有如下: - 媒体查询
- 百分比
- vw/vh
- rem
- 媒体查询
CSS3 中的增加了更多的媒体查询,就像if条件表达式一样,我们可以设置不同类型的媒体条件,并根据对应的条件,给相应符合条件的媒体调用相对应的样式表
使用@Media查询,可以针对不同的媒体类型定义不同的样式,如:
@media screen and (max-width: 1920px) { ... }
当视口在375px - 600px之间,设置特定字体大小18px
@media screen (min-width: 375px) and (max-width: 600px) {body {font-size: 18px;}
}
通过媒体查询,可以通过给不同分辨率的设备编写不同的样式来实现响应式的布局,比如我们为不同分辨率的屏幕,设置不同的背景图片
比如给小屏幕手机设置@2x图,为大屏幕手机设置@3x图,通过媒体查询就能很方便的实现
百分比
通过百分比单位 " % " 来实现响应式的效果
比如当浏览器的宽度或者高度发生变化时,通过百分比单位,可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效果
height、width属性的百分比依托于父标签的宽高,但是其他盒子属性则不完全依赖父元素:
- 子元素的top/left和bottom/right如果设置百分比,则相对于直接非static定位(默认定位)的父元素的高度/宽度
- 子元素的padding如果设置百分比,不论是垂直方向或者是水平方向,都相对于直接父亲元素的width,而与父元素的height无关。
- 子元素的margin如果设置成百分比,不论是垂直方向还是水平方向,都相对于直接父元素的width
- border-radius不一样,如果设置border-radius为百分比,则是相对于自身的宽度
可以看到每个属性都使用百分比,会照成布局的复杂度,所以不建议使用百分比来实现响应式
vw/vh
vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度。 任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一
与百分比布局很相似,在以前文章提过与%的区别,这里就不再展开述说
rem
在以前也讲到,rem是相对于根元素html的font-size属性,默认情况下浏览器字体大小为16px,此时1rem = 16px
可以利用前面提到的媒体查询,针对不同设备分辨率改变font-size的值,如下:
@media screen and (max-width: 414px) {html {font-size: 18px}
}
@media screen and (max-width: 375px) {html {font-size: 16px}
}
@media screen and (max-width: 320px) {html {font-size: 12px}
}
为了更准确监听设备可视窗口变化,我们可以在css之前插入script标签,内容如下:
//动态为根元素设置字体大小
function init () {// 获取屏幕宽度var width = document.documentElement.clientWidth// 设置根元素字体大小。此时为宽的10等分document.documentElement.style.fontSize = width / 10 + 'px'
}
//首次加载应用,设置一次
init()
// 监听手机旋转的事件的时机,重新设置
window.addEventListener('orientationchange', init)
// 监听手机窗口变化,重新设置
window.addEventListener('resize', init)