注意:在我输入此问题时,我遇到了this 问题建议使用
@media query
,但被问到 2011 ...
如您所知,CSS3引入了新的Viewport-percentage length units,vh
和vw
,我认为这对于可靠的响应式布局非常有用,所以我的问题是,是否有任何JavaScript / jQuery替代方案?除了将它用于字体大小之外,是否可以安全地使用尺寸元素?像例子
div {
height: 6vh;
width: 20vh; /* Note am using vh for both, do I need to use vw for width here? */
}
答案 0 :(得分:15)
更新5: .css(属性)修复
像fancyBox这样的插件使用.css('margin-right')
来获取元素的右边距,使用.css('margin-right', '12px')
来设置元素的右边距。这被打破了,因为没有检查props
是否是一个字符串,并且是否有多个参数给出。通过检查props
是否为字符串来修复它。如果是,并且有多个参数,则将参数重写为对象,否则不使用parseProps( $.extend( {}, props ) )
。
更新4:响应式布局的插件https://github.com/elclanrs/jquery.columns(正在进行中)
我给了这个(长期)尝试。首先是CSS示例:http://jsbin.com/orajac/1/edit#css。 (调整输出面板的大小)。请注意,font-size
不适用于视口单元,至少在最新的Chrome上是如此。
这是我尝试用jQuery做的事情。与字体一起使用的jQuery演示版位于http://jsbin.com/izosuy/1/edit#javascript。没有广泛测试它,但它似乎适用于大多数属性,因为它只是将值转换为像素,然后通过调用window.resize
上的插件不断更新。
更新:更新了可与多种浏览器配合使用的代码。如果您使用的是Chrome以外的任何内容,请在本地进行测试,因为jsBin对window.resize
的行为有点奇怪。
更新2:扩展原生css
方法。
更新3:处理插件内部的window.resize事件,以便现在无缝集成。
要点(在本地测试): https://gist.github.com/4341016
/*
* CSS viewport units with jQuery
* http://www.w3.org/TR/css3-values/#viewport-relative-lengths
*/
;(function( $, window ){
var $win = $(window)
, _css = $.fn.css;
function viewportToPixel( val ) {
var percent = val.match(/[\d.]+/)[0] / 100
, unit = val.match(/[vwh]+/)[0];
return (unit == 'vh' ? $win.height() : $win.width()) * percent +'px';
}
function parseProps( props ) {
var p, prop;
for ( p in props ) {
prop = props[ p ];
if ( /[vwh]$/.test( prop ) ) {
props[ p ] = viewportToPixel( prop );
}
}
return props;
}
$.fn.css = function( props ) {
var self = this
, originalArguments = arguments
, update = function() {
if ( typeof props === 'string' || props instanceof String ) {
if (originalArguments.length > 1) {
var argumentsObject = {};
argumentsObject[originalArguments[0]] = originalArguments[1];
return _css.call(self, parseProps($.extend({}, argumentsObject)));
} else {
return _css.call( self, props );
}
} else {
return _css.call( self, parseProps( $.extend( {}, props ) ) );
}
};
$win.resize( update ).resize();
return update();
};
}( jQuery, window ));
// Usage:
$('div').css({
height: '50vh',
width: '50vw',
marginTop: '25vh',
marginLeft: '25vw',
fontSize: '10vw'
});
答案 1 :(得分:14)
我在Android 4.3股票浏览器中遇到此问题(不支持vw,vh等)。 我解决这个问题的方法是使用'rem'作为字体大小的单位并动态地改变< html>使用javascript的字体大小
function viewport() {
var e = window, a = 'inner';
if (!('innerWidth' in window )) {
a = 'client';
e = document.documentElement || document.body;
}
return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}
jQuery(window).resize(function(){
var vw = (viewport().width/100);
jQuery('html').css({
'font-size' : vw + 'px'
});
});
在您的CSS中,您可以使用'rem'代替px,ems等
.element {
font-size: 2.5rem; /* this is equivalent to 2.5vw */
}
以下是代码的演示:http://jsfiddle.net/4ut3e/
答案 2 :(得分:7)
我写了小助手来处理这个问题。它在所有主流浏览器上都受支持并使用jQuery 这是:
SupportVhVw.js
function SupportVhVw() {
this.setVh = function(name, vh) {
jQuery(window).resize( function(event) {
scaleVh(name, vh);
});
scaleVh(name, vh);
}
this.setVw = function(name, vw) {
jQuery(window).resize( function(event) {
scaleVw(name, vw);
});
scaleVw(name, vw);
}
var scaleVw = function(name, vw) {
var scrWidth = jQuery(document).width();
var px = (scrWidth * vw) / 100;
var fontSize = jQuery(name).css('font-size', px + "px");
}
var scaleVh = function(name, vh) {
var scrHeight = jQuery(document).height();
var px = (scrHeight * vh) / 100;
var fontSize = jQuery(name).css('font-size', px + "px");
}
};
如何在HTML中使用它的简单示例:
<head>
<title>Example</title>
<!-- Import all libraries -->
<script type="text/javascript" src="js/libs/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="js/libs/SupportVhVw.js"></script>
</head>
<body>
<div id="textOne">Example text one (vh5)</div>
<div id="textTwo">Example text two (vw3)</div>
<div id="textThree" class="textMain">Example text three (vh4)</div>
<div id="textFour" class="textMain">Example text four (vh4)</div>
<script type="text/javascript">
// Init object
var supportVhVw = new SupportVhVw();
// Scale all texts
supportVhVw.setVh("#textOne", 5);
supportVhVw.setVw("#textTwo", 3);
supportVhVw.setVh(".textMain", 4);
</script>
</body>
可在GitHub上找到:
https://github.com/kgadzinowski/Support-Css-Vh-Vw
JSFiddle上的示例:
http://jsfiddle.net/5MMWJ/2/
答案 3 :(得分:4)
Vminpoly是我所知道的唯一的polyfill - 它在发展之下但是在这篇文章中起作用。静态polyfill也是Jquery Columns和-prefix-free项目的一部分。
答案 4 :(得分:2)
我为这个WITH PURE CSS做了一个非常丑陋但完美的工作方法(不需要JS)。 我遇到了一个充满&#39; vw&#39;的CSS样式表。需要为原生Android浏览器重写的声明(也适用于高度和顶部/底部属性)(版本4.3及以下版本不支持&#39; vw&#39;单位)。
而不是将所有内容重写为百分比,而不是相对于父亲的宽度(所以DOM中的深度,最复杂的计算),这会让我头疼甚至在我达到第一个{height:Xvw之前声明,我自己生成了以下样式表: http://splendige.pl/vw2rem.css
我猜你们都熟悉&#39; em&#39;单位(如果不是:http://www.w3schools.com/cssref/css_units.asp)。经过一些测试后,我发现旧的Android浏览器(以及其他所有浏览器)完全支持“#re; rem”。单位,与&#39; em&#39;相同,但相对于ROOT元素字体大小声明(在大多数情况下,是html标记)。
因此,最简单的方法是声明html标签的字体大小等于视口宽度的1%,例如: 19.2px用于1920px视口,并在整个1920-320px范围内使用大量媒体查询。通过这种方式,我制作了&#39; rem&#39;单位等于&#39; vw&#39;在所有分辨率中(步长为10px,但你甚至可以尝试为每1px声明html {font-size})。然后我只是批量替换&#39; vw&#39;与&#39; rem&#39;并欣赏Android 4.3原生浏览器的工作布局。
更重要的是,您可以重新声明字体大小,甚至是整个身体标签(以您想要的任何单位:px,em,pt等),它不会影响&#39; rem&#39;平等到&#39;&#39;在整个样式表中。
希望这会有所帮助。我知道它看起来有点傻,但就像一个魅力。记住:如果某些东西看起来很愚蠢,但有效,那就不愚蠢了:)
答案 5 :(得分:1)
&#34; jquery.columns&#34;是迄今为止最好的解决方案。
https://github.com/elclanrs/jquery.columns
您只需要2行代码即可转换&#34; vh&#34;进入&#34;全浏览器规模&#34;。
在html中声明一个类:
<img src="example.jpg" class="width50vh" />
然后在javascript:
$('.width50vh').css({width: '50vw'});
答案 6 :(得分:0)
我发布了一个很小的库,可以简化视口相对尺寸的使用。请记住,它不是polyfill,因此它要求您在要调整大小的元素上应用类。例如,<div class="vh10 vw30">hello</div>
将填充10%的高度和30%的宽度。
答案 7 :(得分:0)
我发现的最简单,最优雅的解决方案是简单地创建一个高度为1vh的div;宽度:1vw;当页面加载时,使用getBoundingClientRect()将这些值捕获为像素。然后在文档中添加一个侦听器,以侦听屏幕大小调整并在调整屏幕大小时更新大小。
我将值保存为vh和vw的像素,然后每当我需要使用vh时,我只会说100 * vh,这将给我100vh。
这里是实现的代码段,我的回答是在普通js中,不需要jquery。
function getViewportUnits(){
const placeholder = document.getElementById("placeholder");
const vh = placeholder.getBoundingClientRect().height;
const vw = placeholder.getBoundingClientRect().width;
console.log({vh: vh, vw: vw});
}
#placeholder{
background: red;
height: 1vh;
width: 1vw;
}
<body onload="getViewportUnits()">
<div id="placeholder"></div>