提问人:Axel 提问时间:9/20/2017 最后编辑:Axel 更新时间:2/3/2021 访问量:1927
如何设置带有供应商前缀的 CSS 值(不是属性名称) |客户端
How to set vendor prefixed CSS values (NOT property names) | client-side
问:
<edit>
我实际上猜到了这会发生,但是在发布几秒钟后,我收到了一个“可能重复”的标志,这是不合适的!这个问题是关于CSS值的,而不是关于CSS属性名称的,所以它不是这个或这个问题的重复!!它也不是这个的复制品,因为我要求一个通用的解决方案。
如果你仍然不相信或不确定这篇文章不是关于什么的,也许你可以看看这个问题的底部:“我不在寻找什么”和“谁没有完成工作”</edit>
如果需要,有没有办法通过 JavaScript 在客户端设置适当的供应商前缀 CSS 值?
我在找什么
例如:background: -prefix-linear-gradient{...}
我很想得到一个关于如何通过 JavaScript 在客户端设置供应商前缀的 CSS 值的通用解决方案。除此之外,问题在于如何在客户端执行此操作,而不是作为构建过程的一部分(例如 POSTcss)。
但我也很感激任何提示
- 完成工作的 JavaScript/jQuery 插件或
- 其他资源可以让我自己弄清楚。
正如你所看到的,我已经自己给出了答案。但我仍在寻找更好的解决方案,因为 Autoprefixer 附带了大约 626 KB 的重负载!
使用案例场景
/*
Unprefixed version of "linear-gradient" will only work for
browsers: IE10+, FF16+, Chrome26+, Opera12+, Safari7+.
So how to generate a prefixed version on the fly if necessary?
*/
var aVal = ['linear-gradient(to bottom, #fefefe 0%,#aaaaaa 100%)', 'linear-gradient(to bottom, #aaaaaa 0%,#fefefe 100%']
style = document.getElementsByTagName('BODY')[0].style,
i = 0;
(function toggle () {
if ( i++ ) { i = 0; }
style.background = aVal[ i ];
/* here we need something like:
style.background = parseForPrefix( aVal[ i ] );
*/
setTimeout(toggle, 2000)
})();
* {
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
Unprefixed version of "linear-gradient" will only work for<br>
browsers: IE10+, FF16+, Chrome26+, Opera12+, Safari7+.<br>
So how to generate a prefixed version on the fly if nessecary?
或者想象一下这样的事情
jQuery('head').append('<style>body{background:linear-gradient(...)}</style>')
这应该是这样的
jQuery('head').append('<style>'
+ parseForPrefix('body{background:linear-gradient(...)}') +
'</style>')
相反。
我不是在寻找什么
例如:-prefix-transform: translate{...}
如何在 CSS 属性名称上使用供应商前缀这个主题已经讨论得足够多了(而不是我所追求的)。
注意:我也完全了解作为构建过程一部分使用的预处理器和后处理器。我的整个CSS工作流程都是基于“咕噜咕噜:SASS:PostCSS:Autoprefixer”的,所以没有必要给出任何建议!
谁没有完成工作
- -prefix-free 在以供应商为前缀的 CSS 属性名称上做得很好,但不处理以供应商为前缀的 CSS 值。
- 不幸的是,jQuery也是如此。
答:
为了完成您的要求,您需要一个参考来将当前使用的浏览器与所需的前缀进行比较;像Caniuse一样。或者你可以用CSS@supports规则做一些混合,但这可能比它的价值更麻烦。
有一个现有的解决方案,autoprefixer,但它需要你使用postcss。README 包含各种构建工具插件的示例。我使用 SCSS 和 autoprefixer,我正在实现梦想。
评论
如果您不确定此主题是否与您相关,请阅读“建议 |新手注意事项“首先在此答案的底部。
感谢 Ari 的回答,至少为我指明了正确的方向。此解决方案利用了 Autoprefixer,你们中的大多数人可能会将其与任务运行程序一起用作构建设置的一部分(对我来说也是如此)。
不幸的是,我无法获得有关如何将 Autoprefixer 用作客户端独立版本的信息。因此,我只是看了一下网站,我知道它们正在执行我也想要实现的相同任务(即 Autoprefixer |UI、CodePen、Sassmeister 和 JS Bin)。
这样做的最佳资源是官方的 Autoprefixer |UI 总而言之 - 实际上这没什么大不了的。因此,在这里,我们使用一个非常基本的模型,该模型能够说明......
如何使用 Autoprefixer 客户端
实际上这就是我们所需要的。autoprefixer.process( sInput ).css
但是,让我们将其引导到更真实的类似生活的用例场景中。
// Autoprefixer | ready to rumble
// http://autoprefixer.github.io/assets/code.js?v=1499371172398732683
var sInput = document.getElementById("AutoprefixerIn").innerHTML,
sOutput = autoprefixer.process( sInput, {}, {browsers: ["> 0%"]} ).css;
document.getElementById("AutoprefixerOut").innerHTML = sOutput;
document.getElementById("console-AutoprefixerIn").innerHTML += sInput;
document.getElementById("console-AutoprefixerOut").innerHTML += sOutput;
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Autoprefixer.js | Client-Side</title>
<!-- give snippet a better appearance -->
<style>*{margin:0;padding:0;height:100%;width:100%;}pre{border:2px solid #fff;box-sizing:border-box;overflow:auto;width:50%;}</style>
<!-- Autoprefixer | source, input -->
<!-- IE10+, FF16+, Chrome26+, Opera12+, Safari7+ | prefix for others -->
<style id="AutoprefixerIn">
body {
background: linear-gradient(to bottom, #fefefe 0%,#aaaaaa 100%);
display: flex;
}
</style>
<!-- Autoprefixer | destination, output -->
<style id="AutoprefixerOut"></style>
<!-- Autoprefixer | load library -->
<!-- view-source:http://autoprefixer.github.io/ | line: 140 -->
<script src="https://rawgit.com/ai/autoprefixer-rails/master/vendor/autoprefixer.js" crossorigin="anonymous"></script>
<script> // online fallback in case github is off
window.autoprefixer || document.write('<script src="https://wzrd.in/standalone/autoprefixer@latest">\x3C/script>');
</script>
</head>
<body>
<pre id="console-AutoprefixerIn">
/* display unprefixed original input coming from "style#AutoprefixerIn" */
</pre>
<pre id="console-AutoprefixerOut">
/* display dynamically generated and prefixed output coming from "style#AutoprefixerOut" */
</pre>
专业版
- Autoprefixer 附带了 27 种特殊技巧,这可能使其成为目前可用的最无懈可击的跨浏览器解决方案。
魂斗罗
- Autoprefixer 带有一个沉重的有效载荷,即 626 KB(缩小)。
推荐 |新手须知
- 此解决方案仅适用于必须“即时”将 CSS 添加到网站的开发人员。即便如此,也只有当 CSS 包含必须以供应商为前缀的属性值(例如 、 等)而不是 CSS 属性名称(例如 )。对于依赖跨浏览器 CSS3 功能的插件作者来说,情况很可能就是这样。
linear-gradient
radial-gradient
background
- 另一种情况是,如果您无法通过 JavaScript 控制客户端以外的实际标记。
- 在大多数用例中,处理以供应商为前缀的 CSS 属性名称就足够了(jQuery css 方法也可以这样做)。
- 对于直接交付给客户端(浏览器)的任何 CSS,强烈建议在交付之前在构建设置中准备 CSS。
- 如果您仍然不确定,很可能有更好的解决方案适合您。
PS:在仔细检查所有资源后,我意识到 https://github.com/postcss/autoprefixer#javascript 也指向了正确的方向。
评论
transform
border-radius
transition
linear-gradient
flex
如果属性的值与变量匹配,则可以迭代 、 get 和 属性,例如,用于在 value 前面添加前缀document.styleSheets
"cssRules"
"style"
CSSStyleDeclaration
RegExp
.replace()
const [values, prefix, re = new RegExp(values.join("|"))] = [
["linear-gradient","flex"], "-webkit-"
];
[...document.styleSheets]
.forEach(({cssRules}) => {
const [[{style}], styles = Object.entries(style)] = [cssRules];
if (cssRules.length && styles.some(([, prop]) =>
re.test(prop))) {
console.log(cssRules[0].cssText);
styles
.forEach(([key, prop]) => {
if (re.test(prop)) style[key] = prop.replace(prop, prefix + prop)});
console.log(cssRules[0].cssText);
}
})
body {
background: linear-gradient(to bottom, #fefefe 0%, #aaaaaa 100%);
display: flex;
flex-direction: row;
}
评论
console.log(console.log(cssRules[0].cssText))
.filter()
.forEach()
也许 Modernizr 可以解决这个问题,比如
// returns: -webkit-linear-gradient(left, red, red)
Modernizr.prefixedCSSValue('background', 'linear-gradient(left, red, red)')
工作原理:
// prefixedCSSValue is a way test for prefixed css properties (e.g. display: -webkit-flex)
// @credits modernizr v3.6.0 | Build https://modernizr.com/download?-prefixedcssvalue-dontmin
Modernizr.prototype.prefixedCSSValue = function(prop, value) {
var result = false;
var elem = createElement('div'); // basically: document.createElement.apply(document, ['div'])
var style = elem.style;
if (prop in style) {
var i = domPrefixes.length; // domPrefixes === [ "moz", "o", "ms", "webkit" ] or []
style[prop] = value;
result = style[prop];
while (i-- && !result) {
style[prop] = '-' + domPrefixes[i] + '-' + value;
result = style[prop];
}
}
if (result === '') {
result = false;
}
return result;
};
评论
Modernizr
prefixedCSSValue
autoprefixer
与elem.style.background = 'linear-gradient{...}'
你可以使用elem.style.cssText = 'background:linear-gradient{...}; ...'
这种方法允许您一次向元素添加多个样式,当然是内联的。只会写入浏览器理解的属性。因此,只需采用当前的内联样式(字符串,而不是样式对象)或创建空字符串并添加自己的样式即可。elem.getAttribute('style')
|| ''
let elem = document.getElementById('elem');
let styleAdd = 'background: -prefix-linear-gradient{...}; background: linear-gradient{...};';
elem.style.cssText = (elem.getAttribute('style') || '') + styleAdd;
评论
.css()
linear-gradient()