实心渐变不是真的实心?在色标处不要有清晰的边缘
Solid gradients not really solid? Don't have crisp edges at color stops
在 CSS 中,这似乎是创建纯色渐变的最简单方法,其中颜色在颜色停止处突然结束和开始。示例 -
background-image:linear-gradient(to bottom, gray 100px, white 0); /*Let the browser decide*/
或
background-image:linear-gradient(to bottom, gray 100px, white 100px); /*Explicitly specify.*/
发生的情况是生成了渐变,但在颜色相遇的地方并没有真正清晰的边缘。我的假设是代码会导致灰色在 100px 处停止,而白色紧随其后。
但结果还是有点模糊。我在下面整理了一个示例(将其视为 整页 )。在屏幕中央灰色和白色的交汇处,您可以看到差异。
- 为什么会这样?是因为浏览器需要做的计算吗?
- 有什么方法可以在颜色相遇的地方获得绝对清晰的边缘?
编辑 - 即使是像素值也不是很好。
* {
margin: 0;
padding: 0;
box-sizing:border-box;
}
html,
body {
height: 100%;
}
body {
background: linear-gradient(to bottom, #999 10em, white 0)
}
.container {
width: 50%;
height: 100%;
}
.gradient {
background: #999;
height: 10em;
}
<div class="container">
<div class="gradient"></div>
</div>
正如评论中提到的@Mr Lister,Chrome 看起来像是一个错误。找一台 Mac 机器看看它是否也与 safari 相同。这样我就可以为两者提出错误。
这似乎是一个普遍的错误。它不仅出现在 Chrome 中(最新的 FF 有它),尽管不同的 browsers/engines 有不同的症状和规模。
例如,如果您在一个非常大的元素上放置一个“直边”线性渐变,那么模糊的边缘就会变大。
在 jsfiddle 上查看我的测试用例:http://jsfiddle.net/matvey_andreyev/ufadpo1n/
Chrome 非常高的元素表现得很奇怪。
代码本身:
<div class="padding">
<div id="gradient"></div>
<div class="controls">
<div class="part">
<h3>Demo of a blurry edge where a straight one is expected</h3>
<strong>linear-gradient</strong>( to bottom, transparent,
<br />transparent
<input class="tool" type="text" id="edge1" value="50px" />,
<input type="text" class="tool" id="color2_1" value="#d00" />
<input type="text" class="tool" id="edge2" value="50px" />,
<input type="text" class="tool" id="color2_2" value="#d00" />
<input type="text" class="tool" id="edgeLast" value="100%" />)
<br/> <strong>height:</strong>
<input type="text" class="tool2" id="height" value="300px" />
</div>
<div class="part">
<h4>Some preset examples</h4>
<p><span class="preset" id="default">default values</span>
</p>
<p><span class="preset" id="bigLast">10000px position of the last color stop</span>
</p>
<p><span class="preset" id="edge1greater">1st color stop greater than second</span>
</p>
<p><span class="preset" id="skyscraper">Set great height to the #gradient</span>
</p>
<p>Don't forget viewing in different browsers.</p>
</div>
</div>
</div>
<style type="text/css">
html, body {
min-height:100%;
margin:0;
padding:0;
}
.padding {
padding:20px;
background-color:#ddd;
position:relative;
height:calc(100%);
}
#gradient {
height:300px;
background-position:0 0;
background-image: linear-gradient(to bottom, transparent, transparent 50px, #d00 50px, #d00 100%);
border-style:dotted;
border-width:1px;
border-color:#fff;
}
.controls {
background-color:#fff;
padding:30px 30px 15px;
font-size:13px;
color:#444;
box-shadow:1px 1px 3px rgba(0, 0, 0, 25);
max-width:500px;
position:absolute;
top:30px;
right:30px;
}
h3 {
margin:0 0 .5em;
}
h4 {
margin:0;
}
.tool, .tool2 {
width:40px;
}
.preset {
cursor:pointer;
color:#00d;
border-style:dashed;
border-width:0 0 1px;
}
.preset:hover {
color:#d00;
}
.part {
margin:0 0 15px;
}
</style>
<script type="text/javascript">
$(document).ready(function () {
var $edge1 = $('#edge1'),
$edge2 = $('#edge2'),
$color2_1 = $('#color2_1'),
$color2_2 = $('#color2_2'),
$edgeLast = $('#edgeLast'),
$gradient = $('#gradient'),
$height = $('#height'),
defaultGrad = $gradient.css('background-image'),
defaultHeight = $gradient.css('height'),
setDefaultValues,
changeGrad,
changeHeight;
setDefaultValues = function setDefaultValues() {
$gradient.css({
'background-image': defaultGrad,
'height': defaultHeight
});
$edge1.val('50px');
$edge2.val('50px');
$edgeLast.val('100%');
$color2_1.val('#d00');
$color2_2.val('#d00');
$height.val(defaultHeight);
}
changeGrad = function changeGrad() {
$gradient.css({
'background-image': 'linear-gradient(to bottom, transparent, transparent ' + $edge1.val() + ', ' + $color2_1.val() + ' ' + $edge2.val() + ', ' + $color2_2.val() + ' ' + $edgeLast.val() + ')'
});
}
changeHeight = function changeHeight() {
$gradient.css({
'height': $height.val()
});
}
$('.tool').on('focus blur keyup change', changeGrad);
$('.tool2').on('focus blur keyup change', changeHeight);
$('#default').click(function () {
setDefaultValues();
changeGrad();
});
$('#bigLast').click(function () {
setDefaultValues();
$edgeLast.val('10000px');
changeGrad();
});
$('#edge1greater').click(function () {
setDefaultValues();
$edge1.val('55px');
changeGrad();
});
$('#skyscraper').click(function () {
$height.val(50000 + 'px');
changeHeight();
});
});
</script>
目前似乎没有真正的答案。我最终使用了背景图像而不是最后的线性渐变。
在 CSS 中,这似乎是创建纯色渐变的最简单方法,其中颜色在颜色停止处突然结束和开始。示例 -
background-image:linear-gradient(to bottom, gray 100px, white 0); /*Let the browser decide*/
或
background-image:linear-gradient(to bottom, gray 100px, white 100px); /*Explicitly specify.*/
发生的情况是生成了渐变,但在颜色相遇的地方并没有真正清晰的边缘。我的假设是代码会导致灰色在 100px 处停止,而白色紧随其后。
但结果还是有点模糊。我在下面整理了一个示例(将其视为 整页 )。在屏幕中央灰色和白色的交汇处,您可以看到差异。
- 为什么会这样?是因为浏览器需要做的计算吗?
- 有什么方法可以在颜色相遇的地方获得绝对清晰的边缘?
编辑 - 即使是像素值也不是很好。
* {
margin: 0;
padding: 0;
box-sizing:border-box;
}
html,
body {
height: 100%;
}
body {
background: linear-gradient(to bottom, #999 10em, white 0)
}
.container {
width: 50%;
height: 100%;
}
.gradient {
background: #999;
height: 10em;
}
<div class="container">
<div class="gradient"></div>
</div>
正如评论中提到的@Mr Lister,Chrome 看起来像是一个错误。找一台 Mac 机器看看它是否也与 safari 相同。这样我就可以为两者提出错误。
这似乎是一个普遍的错误。它不仅出现在 Chrome 中(最新的 FF 有它),尽管不同的 browsers/engines 有不同的症状和规模。
例如,如果您在一个非常大的元素上放置一个“直边”线性渐变,那么模糊的边缘就会变大。
在 jsfiddle 上查看我的测试用例:http://jsfiddle.net/matvey_andreyev/ufadpo1n/ Chrome 非常高的元素表现得很奇怪。
代码本身:
<div class="padding">
<div id="gradient"></div>
<div class="controls">
<div class="part">
<h3>Demo of a blurry edge where a straight one is expected</h3>
<strong>linear-gradient</strong>( to bottom, transparent,
<br />transparent
<input class="tool" type="text" id="edge1" value="50px" />,
<input type="text" class="tool" id="color2_1" value="#d00" />
<input type="text" class="tool" id="edge2" value="50px" />,
<input type="text" class="tool" id="color2_2" value="#d00" />
<input type="text" class="tool" id="edgeLast" value="100%" />)
<br/> <strong>height:</strong>
<input type="text" class="tool2" id="height" value="300px" />
</div>
<div class="part">
<h4>Some preset examples</h4>
<p><span class="preset" id="default">default values</span>
</p>
<p><span class="preset" id="bigLast">10000px position of the last color stop</span>
</p>
<p><span class="preset" id="edge1greater">1st color stop greater than second</span>
</p>
<p><span class="preset" id="skyscraper">Set great height to the #gradient</span>
</p>
<p>Don't forget viewing in different browsers.</p>
</div>
</div>
</div>
<style type="text/css">
html, body {
min-height:100%;
margin:0;
padding:0;
}
.padding {
padding:20px;
background-color:#ddd;
position:relative;
height:calc(100%);
}
#gradient {
height:300px;
background-position:0 0;
background-image: linear-gradient(to bottom, transparent, transparent 50px, #d00 50px, #d00 100%);
border-style:dotted;
border-width:1px;
border-color:#fff;
}
.controls {
background-color:#fff;
padding:30px 30px 15px;
font-size:13px;
color:#444;
box-shadow:1px 1px 3px rgba(0, 0, 0, 25);
max-width:500px;
position:absolute;
top:30px;
right:30px;
}
h3 {
margin:0 0 .5em;
}
h4 {
margin:0;
}
.tool, .tool2 {
width:40px;
}
.preset {
cursor:pointer;
color:#00d;
border-style:dashed;
border-width:0 0 1px;
}
.preset:hover {
color:#d00;
}
.part {
margin:0 0 15px;
}
</style>
<script type="text/javascript">
$(document).ready(function () {
var $edge1 = $('#edge1'),
$edge2 = $('#edge2'),
$color2_1 = $('#color2_1'),
$color2_2 = $('#color2_2'),
$edgeLast = $('#edgeLast'),
$gradient = $('#gradient'),
$height = $('#height'),
defaultGrad = $gradient.css('background-image'),
defaultHeight = $gradient.css('height'),
setDefaultValues,
changeGrad,
changeHeight;
setDefaultValues = function setDefaultValues() {
$gradient.css({
'background-image': defaultGrad,
'height': defaultHeight
});
$edge1.val('50px');
$edge2.val('50px');
$edgeLast.val('100%');
$color2_1.val('#d00');
$color2_2.val('#d00');
$height.val(defaultHeight);
}
changeGrad = function changeGrad() {
$gradient.css({
'background-image': 'linear-gradient(to bottom, transparent, transparent ' + $edge1.val() + ', ' + $color2_1.val() + ' ' + $edge2.val() + ', ' + $color2_2.val() + ' ' + $edgeLast.val() + ')'
});
}
changeHeight = function changeHeight() {
$gradient.css({
'height': $height.val()
});
}
$('.tool').on('focus blur keyup change', changeGrad);
$('.tool2').on('focus blur keyup change', changeHeight);
$('#default').click(function () {
setDefaultValues();
changeGrad();
});
$('#bigLast').click(function () {
setDefaultValues();
$edgeLast.val('10000px');
changeGrad();
});
$('#edge1greater').click(function () {
setDefaultValues();
$edge1.val('55px');
changeGrad();
});
$('#skyscraper').click(function () {
$height.val(50000 + 'px');
changeHeight();
});
});
</script>
目前似乎没有真正的答案。我最终使用了背景图像而不是最后的线性渐变。