您的位置:首页 > Web前端 > CSS

CSS3实现的响应式字体:自适应视图窗口大小的新单位

2015-11-13 01:14 701 查看


viewpoint

css3提供了一些与当前viewpoint相关的元素,vw,vh,vim等。

“viewpoint” = window size

vw = 1% of viewport width
1vh = 1% of viewport height
1vmin = 1vw or 1vh, 最小
1vmax = 1vw or 1vh, 最大


兼容性:chrome 20+/ safari 6+/ IE 10+ / FF 19+ / IOS 6+

DEMO地址:http://qianduannotes.sinaapp.com/test/fontResize.html  (已经用JS修正重绘bug)

<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<style type="text/css">
#box { font-size: 4vw;}
</style>
</head>

<body>
<div id="box">
我是靖鸣君 我是靖鸣君 我是靖鸣君
</div>
</body>
</html>


但是该方案存在一个bug,上面的代码,当浏览器窗口变化的时候,box中的文字并没有按照应有的比例变化,但是css3标准中是这么说的:

When the height or width of the viewport is changed, they are scaled accordingly.

 像这样的问题,我之前也遇到过,比如以下代码:(小插曲,可跳过)

<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>CSS3 Demo</title>
<style type="text/css">
body, div { margin:0; padding: 0;}
.wrap { background: blue; width: 100%;}
.box { width: 900px; height: 200px;}
</style>
</head>

<body>
<div class="wrap"><div class="box"></div></div>
</body>
</html>


 

DEMO地址:http://qianduannotes.sinaapp.com/test/paintBug.html

box的宽度设置为900px,wrap设置为100%;缩小浏览器窗口,当宽度小于900时会出现滚动条,向右滚动,会发现蓝色部分并不是100%,这个问题大家可以去思考下。

 


bug处理

回到上面的问题,font-size:4vw,应该会使得字体的大小变化,可是他没有,和标准说的不一样,所以可以认为是一个bug。

window.onresize = function(){
var box = document.getElementById("box");
box.style["z-index"] = 1;
}


 z-index可以对应的元素被重绘(repaint)。

 

 延伸一点点关于重绘(repaint)和回流(reflow)的知识:



1. 添加、删除元素(回流+重绘)
2. 隐藏元素,display:none(回流+重绘),visibility:hidden(只重绘,不回流)
3. 移动元素,比如改变top,left(jquery的animate方法就是,改变top,left不一定会影响回流),或者移动元素到另外1个父元素中。(重绘+回流)
4. 对style的操作(对不同的属性操作,影响不一样)
5. 还有一种是用户的操作,比如改变浏览器大小,改变浏览器的字体大小等(回流+重绘)
让我们看看下面的代码是如何影响回流和重绘的:
var s = document.body.style;
s.padding = "2px"; // 回流+重绘
s.border = "1px solid red"; // 再一次 回流+重绘
s.color = "blue"; // 再一次重绘
s.backgroundColor = "#ccc"; // 再一次 重绘
s.fontSize = "14px"; // 再一次 回流+重绘
// 添加node,再一次 回流+重绘


关于重绘和回流

 


 其他方案

1. css expression, 这个效率比较低,不推荐使用

#box { star:expression(onresize = function(){
var res = parseInt(this.style.width) / 20;
res = res < 9 : "9px" ? res + "px";
this.style.fontSize = res;
});
}
//P.S:上面代码没测试,不知道写错没有


与其说用的css,还不如说是JS,而且是效率不够的JS。

 

2. media query,这东西也不是特别好用

h2{
font-size:25px
}

@media screen and (max-width: 850px){/* 可视区域小于 850px, 设置更小font-size属性 */
h2{
font-size:19px;
}
}


用media query会使得字体的变化出现不连贯性,而且要可能设置多个@media,相当麻烦。

 

3. media query + -webkit-transition 实现平滑转变

 DEMO地址:http://qianduannotes.sinaapp.com/test/fontResize2.html

div{
font-size: 40px;
-webkit-transition:font-size 0.2s ease-out;
}

@media only screen and (max-width: 1200px) { div{ font-size: 39px; }}
@media only screen and (max-width: 1100px) { div{ font-size: 38px; }}
@media only screen and (max-width: 1000px) { div{ font-size: 37px; }}
@media only screen and (max-width: 900px) { div{ font-size: 36px; }}
@media only screen and (max-width: 800px) { div{ font-size: 35px; }}
@media only screen and (max-width: 700px) { div{ font-size: 34px; }}
@media only screen and (max-width: 600px) { div{ font-size: 33px; }}
@media only screen and (max-width: 500px) { div{ font-size: 32px; }}
@media only screen and (max-width: 400px) { div{ font-size: 31px; }}
@media only screen and (max-width: 300px) { div{ font-size: 30px; }}


我最近在做一个项目。客户要求标题可以根据用户屏幕的尺寸而自动改变大小。我知道我通常用的相对字体单位(注* 如px, pt, em)只是相对于HTML根元素的大小而自动改变,而不是相对于用户的屏幕。

在上网查询之后我发现一种新的字体大小单位,叫做:Viewport-Percentage Lengths.

我是在一MDN的一篇文章中发现这个Viewport-percentage lengths的,这正是我要找的东西,我只是不知道它叫什么。


它是怎么工作的?

其实非常简单。一个单位相于当前视图窗口大小的1%,宽度和高度是不同的,分别用(vw, vh)表示。你可以通过vmin和vmax设置最大最小值。

1vw = 当前视图窗口(viewport)1%的宽度

1vh = 当前视图窗口(viewport)1%的高度

1vmin = 1vw 或 1vh, 取决于哪个更小一点

1vmax = 1vw 或 1vh, 取决于哪个更大一点

如果当前视图窗口宽度是100毫米,那么5vw就是5毫米。

vmin 和 vmax 的设置就像这样:
section {
width: 100vmin;
background-color: #ff5442;
}


示例

这里有一份完整的示例2

注* Bootstrap之类的响应式布局CSS框架多采用 @media (max-width: *) {} 之类响应式样示实现。
// 屏幕宽度小于767个象素时应用的CSS样式@media (max-width: 767px) {//CSS代码}// 屏幕宽度在767和991象素之间的CSS样式@media (min-width: 768px) and (max-width: 991px) {//CSS代码}

此法在大小在跨过临界值时才会发生改变。而vh,vw这样的单位会随窗口大小而立刻发生改变。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: