是否有任何跨浏览器的 javascript 可以使 vh 和 vw 单元工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13948713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there any cross-browser javascript for making vh and vw units work
提问by Mr. Alien
Note: Ok while I was typing this question I came across thisquestion which suggests to use
@media querybut was asked back in 2011...
注意:好的,当我输入这个问题时,我遇到了这个问题,它建议使用
@media query但在 2011 年被问到......
As you know CSS3 introduces new Viewport-percentage length units, vhand vw, which I feel are really useful for a solid responsive layout, so my question is, is there any JavaScript/jQuery alternative for this? More over apart from using it for font sizes, is it safe to use for sizing elements? Like example
正如你所知道CSS3引入了新的视口百分比长度单位,vh并且vw,我觉得是非常有用了坚实的响应式布局,所以我的问题是,是否有任何的JavaScript / jQuery的替代这个?除了将其用于字体大小之外,用于调整元素大小是否安全?喜欢的例子
div {
height: 6vh;
width: 20vh; /* Note am using vh for both, do I need to use vw for width here? */
}
采纳答案by elclanrs
Update 5:.css(property) fix
Plugins like fancyBoxuse .css('margin-right')to fetch the right margin of an element and .css('margin-right', '12px')to set the right margin of an element. This was broken, because there was no check if propsis a string and if there are multiple arguments given. Fixed it by checking if propsis a string. If so and there is multiple arguments, arguments is rewritten into an object, otherwise parseProps( $.extend( {}, props ) )is not used.
更新5:的CSS(属性)修复插件等的fancybox使用.css('margin-right')抓取元件的右边距与.css('margin-right', '12px')设置元素的右边缘。这被破坏了,因为没有检查是否props是字符串以及是否给出了多个参数。通过检查是否props为字符串来修复它。如果是这样并且有多个参数,则将参数重写到一个对象中,否则parseProps( $.extend( {}, props ) )不使用。
Update 4:Plugin for responsive layouts https://github.com/elclanrs/jquery.columns(in the works)
更新 4:响应式布局插件https://github.com/elclanrs/jquery.columns(正在开发中)
I gave this a (long) try. First here's the CSS example: http://jsbin.com/orajac/1/edit#css. (resize the output panel). Notice that the font-sizedoesn't work with viewport units, at least on latest Chrome.
我给了这个(长时间)尝试。首先是 CSS 示例:http: //jsbin.com/orajac/1/edit#css。(调整输出面板的大小)。请注意,font-size不适用于视口单位,至少在最新的 Chrome 上是这样。
And here's my attempt at doing this with jQuery. The jQuery demo which works with the font as well is at http://jsbin.com/izosuy/1/edit#javascript. Haven't tested it extensively but it seems to work with most properties since it's just converting the values to pixel and then by calling the plugin on window.resizeit keeps updating.
这是我用 jQuery 做这件事的尝试。使用该字体的 jQuery 演示也位于http://jsbin.com/izosuy/1/edit#javascript。尚未对其进行广泛测试,但它似乎适用于大多数属性,因为它只是将值转换为像素,然后通过调用插件window.resize不断更新。
Update:Updated code to work with many browsers. Test locally if you're using anything other than Chrome because jsBin acts a bit weird with window.resize.
更新:更新了代码以适用于许多浏览器。如果您使用 Chrome 以外的任何东西,请在本地进行测试,因为 jsBin 对window.resize.
Update 2:Extend native cssmethod.
更新 2:扩展本机css方法。
Update 3:Handle window.resize event inside of the plugin so the integration is now seamless.
更新 3:处理插件内的 window.resize 事件,以便现在无缝集成。
The gist (to test locally):https://gist.github.com/4341016
要点(在本地测试):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'
});
回答by Alexandru Bangal?
I am facing this issue with the Android 4.3 stock browser (doesn't support vw,vh, etc). The way I solved this is using 'rem' as a font-size unit and dynamically changing the < html >'s font-size with javascript
我在使用 Android 4.3 股票浏览器时遇到了这个问题(不支持 vw、vh 等)。我解决这个问题的方法是使用 'rem' 作为字体大小单位并使用 javascript 动态更改 <html> 的字体大小
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'
});
});
and in your css you can use 'rem' instead of px,ems,etc
在你的 css 中,你可以使用“rem”而不是 px、ems 等
.element {
font-size: 2.5rem; /* this is equivalent to 2.5vw */
}
Here's a demo of the code : http://jsfiddle.net/4ut3e/
这是代码的演示:http: //jsfiddle.net/4ut3e/
回答by Konrad G
I wrote small helper to deal with this problem. It's supported on all main browsers and uses jQuery.
Here it is:
我写了小帮手来处理这个问题。所有主要浏览器都支持它并使用 jQuery。
这里是:
SupportVhVw.js
支持VhVw.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");
}
};
Simple example how to use it in HTML:
如何在 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>
It's available on GitHub:
https://github.com/kgadzinowski/Support-Css-Vh-Vw
Example on JSFiddle:
http://jsfiddle.net/5MMWJ/2/
它在 GitHub 上可用:
https: //github.com/kgadzinowski/Support-Css-Vh-Vw
JSFiddle 示例:http:
//jsfiddle.net/5MMWJ/2/
回答by RobW
Vminpolyis the only polyfill I know of —?it's under develpment but works as of this post. There are static polyfills as part of the Jquery Columnsand -prefix-freeprojects as well.
Vminpoly是我所知道的唯一一个polyfill—?它正在开发中,但在这篇文章中有效。Jquery Columns和-prefix-free项目中也包含静态 polyfill 。
回答by k0m0r
I've just made a very ugly, but perfectly working workaround for this WITH PURE CSS (no JS needed). I came across a CSS stylesheet full of 'vw' declarations (also for heights and top/bottom properties) that needed to be rewritten for native Android Browser (which in versions 4.3 and below does NOT support 'vw' units).
我刚刚使用 PURE CSS(不需要 JS)为此做了一个非常丑陋但完美的解决方法。我遇到了一个充满“vw”声明(也用于高度和顶部/底部属性)的 CSS 样式表,需要为原生 Android 浏览器(在 4.3 及以下版本不支持“vw”单位)重写。
Instead of rewriting everything to percentages, that are relative to parent's width (so the deeper in DOM, the most complicated calculations), which would give me a headache even before I would reach the first { height: Xvw } declaration, I generated myself the following stylesheet: http://splendige.pl/vw2rem.css
不是将所有内容都重写为相对于父级宽度的百分比(因此在 DOM 中更深,最复杂的计算),这甚至在我到达第一个 { height: Xvw } 声明之前都会让我头疼,我自己生成了以下样式表:http: //splendige.pl/vw2rem.css
I guess you're all familiar with 'em' units (if not: http://www.w3schools.com/cssref/css_units.asp). After some testing I discovered that old Android Browsers (as well as all the others) perfectly support the 'rem' units, which work the same as 'em', but are relative to the ROOT element font-size declaration (in most cases, the html tag).
我想你们都熟悉“em”单位(如果不是:http: //www.w3schools.com/cssref/css_units.asp)。经过一些测试,我发现旧的 Android 浏览器(以及所有其他浏览器)完全支持“rem”单位,其工作方式与“em”相同,但相对于 ROOT 元素字体大小声明(在大多数情况下, html 标签)。
So the easiest way to make this work was to declare the font-size for html tag that is equal to 1% of the viewport's width, e.g. 19.2px for 1920px viewport and use a lot of media queries for the whole 1920-320px range. This way I made the 'rem' unit equal to 'vw' in all resolutions (step is 10px, but you can even try declaring html{font-size} for every 1px). Then I just batch-replaced 'vw' with 'rem' and admired the working layout on Android 4.3 native browser.
因此,使这项工作最简单的方法是声明 html 标签的字体大小等于视口宽度的 1%,例如,1920 像素视口为 19.2 像素,并在整个 1920-320 像素范围内使用大量媒体查询。通过这种方式,我在所有分辨率下都使“rem”单位等于“vw”(步长为 10px,但您甚至可以尝试为每 1px 声明 html{font-size})。然后我只是用 'rem' 批量替换了 'vw' 并欣赏了 Android 4.3 本机浏览器上的工作布局。
Whatsmore, you can then redeclare the font-size even for the whole body tag (in whatever units you want: px, em, pt, etc.) and it does NOT affect the 'rem' equality to 'vw' in the whole stylesheet.
更重要的是,您甚至可以为整个 body 标记重新声明字体大小(以您想要的任何单位:px、em、pt 等),并且它不会影响整个样式表中“rem”与“vw”的相等性.
Hope this helps. I know it looks kinda silly, but works like a charm. Remember: if something looks stupid, but works, it is not stupid :)
希望这可以帮助。我知道它看起来有点傻,但效果很好。请记住:如果某件事看起来很愚蠢,但有效,那它并不愚蠢:)
回答by stonyau
"jquery.columns" is so far the best solutions.
“jquery.columns”是迄今为止最好的解决方案。
https://github.com/elclanrs/jquery.columns
https://github.com/elclanrs/jquery.columns
You only need 2 lines of codes to turn "vh" into a "all-browser scale".
您只需要 2 行代码即可将“vh”变成“全浏览器规模”。
Declare a class in html:
在 html 中声明一个类:
<img src="example.jpg" class="width50vh" />
Then in javascript:
然后在javascript中:
$('.width50vh').css({width: '50vw'});
回答by Chance
The simplest and most elegant solution I have found is to simply make a div that has height: 1vh; and width: 1vw; and when the page loads grab those values as pixels with getBoundingClientRect(). then add a listener to the document to listen for screen resizing and update the size when screen is resized.
我发现的最简单和最优雅的解决方案是简单地制作一个高度为 1vh 的 div;和宽度:1vw;当页面加载时,使用 getBoundingClientRect() 将这些值作为像素获取。然后向文档添加一个侦听器以侦听屏幕调整大小并在调整屏幕大小时更新大小。
I save the value in pixels of the vh and vw and then whenever I need to use vh i would just say 100 * vh which would give me 100vh.
我保存了 vh 和 vw 的像素值,然后每当我需要使用 vh 时,我都会说 100 * vh,这会给我 100vh。
Here is a code snippet on it's implementation, my answer is in vanilla js, no need for jquery.
这是关于它的实现的代码片段,我的答案是在 vanilla 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>
回答by Jo?o Cunha
I've published a tiny lib that eases viewport-relative dimensions usage. Keep in mind it's not a polyfill, so it requires that you apply classes on the elements you want to resize. For instance, <div class="vh10 vw30">hello</div>will fill 10% of the height and 30% of the width.
我发布了一个小库,可以简化视口相对尺寸的使用。请记住,它不是一个 polyfill,因此它要求您在要调整大小的元素上应用类。例如,<div class="vh10 vw30">hello</div>将填充高度的 10% 和宽度的 30%。
Check it out: https://github.com/joaocunha/v-unit

