如何处理两个重叠的div的‘双重不透明度’问题

36
我有两个div,都设置了0.6的不透明度。我需要它们重叠但保持各自的不透明度,不要创建一个新的混合不透明度级别。我不能使用图像。
编辑 - 小圆圈应该有一个canvas元素。不确定伪元素是否是最佳解决方案。
有没有CSS的方法可以做到这一点,或者我应该只使用canvas?
示例 -

http://dabblet.com/gist/1566209

HTML:

<div id="foo">
    <div id="bar">
    </div>
</div>

CSS:

/**
 * Double Opacity
 */
body{background:green;}

#foo{
height:150px;
width:250px;
background:rgba(0, 0, 0, 0.6);
position:absolute;
left:40%;
top:20%;
}

#bar{
height:40px;
width:40px;
background:rgba(0, 0, 0, 0.6);
border-radius:40px;
position:absolute;
top:-15px;
left:-15px;
}

1
你的意思是,你希望重叠区域的不透明度也具有0.6的表现值吗? - dgvid
2
我不确定那是可能的。那是不透明度的自然功能。至少用CSS来说是不行的... - Dan
这是一个很棒的问题!非常期待解决方案(=黑客)(如果有的话)。 - Rudie
附注:Dabblet 看起来作为 jsFiddle 的替代品很酷。可惜它在 Safari 中根本无法工作……无限加载和控制台中的语法错误。 - Sparky
2
Dabbblet的编辑器很糟糕,而jsFiddle的编辑器几乎完美。 - Rudie
5个回答

49

摘要:


根据需要的内容不同,可能会有些棘手,但基本的方法是相当简单明了的。


这种方法与我的第一个想法有点不同...但是结果相同。

  1. 我为圆形制作了一个黑色/透明的图案,并将其设置为:before
  2. 然后将圆形变换rotate(180deg)并移动到适合<div>角落的位置。
  3. 然后我将该圆形的opacity设置为0.6
  4. <div>本身不受opacity的影响。
  5. 接下来,我添加了:after元素,并将图像作为background(如果需要,可以通过js控制)
  6. 我对图像添加了一些效果(border-radiusbox-shadowborder),以展示这个元素可以轻松独立地进行控制。
  7. 我使用了较浅的背景,并将opacity设置为0.3以显示结果

这里是FIDDLE的链接: http://jsfiddle.net/pixelass/nPjQh/4/

看看这个版本,会有一些疯狂的结果: http://jsfiddle.net/pixelass/nPjQh/5/

每个例子都只使用一个div元素

基本规则。(这些规则“可以”用于创建与js动态行为)

position = absolute;

top = circleHeight / -2;

left = circleHeight / -2; //(left = top)

rotation = 180度;

opacity = 背景值;

bgColor = 背景的RGB值;

#inner {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    z-index: -1;
    background-color: rgba(0, 0, 0, 0.3);
    padding:20px;
    border-radius: 20px;
    border-top-left-radius: 0;
}
#inner:before {
    content: "";
    background-image: -webkit-linear-gradient(transparent 50%, rgb(0, 0, 0) 50%, rgb(0, 0, 0)),
        -webkit-linear-gradient(0deg, transparent 50%, rgb(0, 0, 0) 50%, rgb(0, 0, 0));
    height: 40px;
    width: 40px;
    border-radius: 40px;
    position: absolute;
    top: -20px;
    left: -20px;
    -webkit-transform: rotateZ(180deg);
    opacity:0.3;
}
#inner:after {
    content: "";
    background: url('http://lorempixel.com/10/10/sports/1/') no-repeat;
    background-position:0;
    height: 10px;
    width: 10px;
    border-radius: 10px;
    position: absolute;
    top: -6px;
    left: -6px;
    -webkit-box-shadow: 0 0 10px rgb(255,255,255);
    border: 1px rgb(255,255,255) solid;

}

更好的解释


原始的注释版本 http://jsfiddle.net/pixelass/nPjQh/10/

请查看下面代码中的注释

#inner {
background: rgba(0,0,0,0.5) /*this is the full color-code of the div (with alpha)*/
}
#inner:before {
    /*the solid color of the circle = rgbValue of the div*/
    background-image: -webkit-linear-gradient(transparent 50%, rgb(0, 0, 0) 50%, rgb(0, 0, 0)),
        -webkit-linear-gradient(0deg, transparent 50%, rgb(0, 0, 0) 50%, rgb(0, 0, 0));
    /*opacity of the circle = alpha of the div*/
    opacity: 0.5;
}

这个例子有一个完全透明的 div ...圆形是“吃豆人”形状:http://jsfiddle.net/pixelass/nPjQh/14/

pacman shaped circle


管理圆的偏移量


看一下这些处理圆形偏移的例子(不使用伪元素

OP代码的1:1复制(15像素偏移):http://jsfiddle.net/pixelass/nPjQh/12/

更小的偏移量(5像素):http://jsfiddle.net/pixelass/nPjQh/13/

(内容与圆形具有相同的不透明度)

偏移是如何工作的?

控制background-sizetopleft之间的关系

规则

top = left;

background-size = elementHeight * 2 + top * 2;

看这朵花(它也只是一个带伪元素的<div>),background-size比圆形大,从而在底部创建了绿色的叶子。

http://jsfiddle.net/pixelass/nPjQh/15/

one div makes a flower


当前问题


请查看这个代码片段:http://jsfiddle.net/pixelass/nPjQh/16/

如果不像帖子顶部的示例那样使用另一层,则内容将是透明的。因此,如果您只需要在圆圈内放置图像,则上面的示例将很好地解决问题。

conent is transparent

如何解决这个问题

如果您需要在圆形内部放置画布或另一个div,则必须将圆形放在div上,并将所需的div层叠在圆形上方

请参见此fiddle:http://jsfiddle.net/pixelass/nPjQh/17/

稍作更改即可正常工作。从FIDDLE获取代码

correcting the opacity issue


不同的形状/高级样式


如果您使用具有平面边的不同形状,甚至可以在两个div的总和周围添加边框...或者甚至添加一个盒子阴影

仍然使用简单的标记...

<div id="foo">
    <div id="bar">
    </div>
</div>

请查看以下 jsfiddle 链接以获取 box-shadow 的代码示例: http://jsfiddle.net/pixelass/nPjQh/21/

adding a box-shadow


给圆形添加边框


使用-webkit-mask-image,我们可以为圆形添加边框。 http://jsfiddle.net/pixelass/nPjQh/24/

border on round element


更多例子:


周围四个圆圈

http://jsfiddle.net/pixelass/nPjQh/25/

标记:

<div id="foo">
    <div id="bar1"></div>
    <div id="bar2"></div>
    <div id="bar3"></div>
    <div id="bar4"></div>
</div>

4 circles

使用这种技术制作工具提示

http://jsfiddle.net/pixelass/nPjQh/31/

标记:

<div id="foo">
    <div id="bar"></div>
    I am a pure css tooltip with a semi-transparent background and a black border. <br/>
    My width is static an my height is dynamic...
</div>

css tooltip


重叠区域永远不会改变。我不明白背景渐变是如何工作的。如果可以,请提供一个示例。 - tripleZee
太棒了 =) 但是为什么这个不起作用?http://jsfiddle.net/rudiedirkx/nPjQh/9/ 我不理解这些渐变...我想让圆形背景是 rgba(0, 0, 0, 0.5),但现在它不是“纯黑色”。 - Rudie
2
@pixelass 啊,对了,opacity!我错过了那个 =) 我敢说这太棒了。为什么这个答案只有两个赞?你的疯狂例子真是太棒了!我一定会在某个地方使用它。 - Rudie
@Rudie 谁在乎投票。这应该被标记为已回答。我还添加了一个带边框的圆形示例。 - user950658
你的几乎所有小提琴示例在我的Firefox 8中都无法工作(我认为IE也是如此,尽管我没有检查过)。毫无疑问,这是因为您正在使用webkit函数来实现效果。虽然我确实钦佩您在这方面所做的工作,但我不确定您对此进行游说并将其视为“答案”的做法是否完全有效。 - ScottS
显示剩余13条评论

14

2
是的,但那也会修改文本的不透明度。 - Roko C. Buljan
真的。+1给(我认为唯一)合理的答案(使用两个div!)。 - Roko C. Buljan
很不幸,#foo div 中有很多内容无法透明。 - tripleZee
这个答案应该被踩,因为它并不比其他“错误”的答案更好。即使是Rudi的答案也比这个好。对于我方的踩票表示歉意。 - user950658
虽然这回答了问题,但最好在 Stack Overflow 上添加代码,而不是在第三方网站上。 - Heretic Monkey
显示剩余3条评论

2
这个怎么样: http://jsfiddle.net/rudiedirkx/TqRCw/ (Dabble的编辑器很糟糕!!)很遗憾,这不能只用伪元素实现 =( 但是只使用伪元素也可以实现!请参见pixelass的答案。但需要CSS3支持。

这可以很容易地完成,无需任何特殊的标记或伪元素...相信我,这真的很简单...一个小时或两个小时后回家...然后我会给出这个问题的正确答案... - user950658
+1--我刚刚看了你的答案,发现它几乎和我的一模一样(只是你发布得比我早,并且你的稍微更优雅一些)。 - ScottS
工作得很好,但我需要在那个小圆圈里放置一张图片或画布元素。 - tripleZee
你可以为伪元素添加背景,但不能在伪元素内部添加元素。显然,你可以用真实元素替换伪元素,但我喜欢语义化,而这不是它的表现形式。 - Rudie
抱歉这里注释有些多啊 ;) ... 我在我的回答中添加了一个带有图片的示例... 不管怎样,谢谢这个问题。我喜欢这样的东西 :D 对于这个问题+1... - user950658
显示剩余2条评论

2

修订答案

这个代码片段与IE9 兼容,解决了我原来答案中需要重复背景的问题。它使用伪元素生成圆形。这个解决方案源于pixelass的“吃豆人”想法,只是不像使用新的背景渐变CSS生成,而是使用旧的(并且很少被使用或理解clip属性将圆分为两部分。这解决了你的圆在角落上没有“居中”的问题。

#foo {
    height:150px;
    width:250px;
    background: rgba(0, 0, 0, 0.6);
    position:absolute;
    left:40%;
    top:20%;
}

#bar {
    height:40px;
    width:40px;
    position:absolute;
    top:-15px;
    left:-15px;
    line-height: 40px;
}

#bar:before,
#bar:after {
    content: '';
    display: block;
    background: rgba(0, 0, 0, 0.6);
    border-radius: 40px;
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: -1;
    top: 0;
    left: 0;
}

#bar:before {
    clip: rect(0 40px 15px 0);
}

#bar:after {
    clip: rect(15px 15px 40px 0);
}

原始答案

你可以这样做(查看fiddle)。它将圆形推到下面,并使用伪元素“覆盖”与其重叠的部分,以重新建立body的背景颜色:

body{background:green;}

#foo{
height:150px;
width:250px;
background:rgba(0, 0, 0, 0.6);
position:absolute;
left:40%;
top:20%;
}

#bar{
height:40px;
width:40px;
background:rgba(0, 0, 0, 0.6);
border-radius:40px;
position:absolute;
top:-15px;
left:-15px;
z-index: -1;
}

#bar:after {
    content: '';
    display: block;
    background: green;
    position: absolute;
    right: 0;
    bottom: 0;
    width: 25px;
    height: 25px;
}

还不错,但绿色只是一个例子。如果不知道背景颜色,你会如何处理它? - tripleZee
@tripleZee--好问题。我重新表述了一个答案。它仍然有一个小问题需要解决,因为你的圆圈不在角落中心。 - ScottS
@tripleZee--我已经解决了圆形偏离中心的问题。 - ScottS
OP应该提到他正在寻找适用于iPhone的方法。尽管您的版本支持IE9,但它不兼容iPhone(我的也是如此)。您的版本有微小的重叠,而我的则有微小的间隙...无论如何,感谢IE9的支持。 - user950658
是的,关于iPhone的那部分信息会很有用。我不确定你上次看的是哪个版本,但我在最新版本中没有看到微小的重叠。 - ScottS

0

我已经创建了一个Q/A来处理这种情况,同时还包括处理这些重叠元素的“悬停”。

使用不透明度处理重叠元素以及如何处理它们的“悬停”

解决方案基本上是在父级别中设置不透明度,而不是直接在子元素上设置,并使用JS在悬停时切换它们。


HTML

<div class="wrapper">
  <div class="first"></div>
  <div class="second"></div>
</div>

JS

$(".first, .second").hover(function() {
  $(".wrapper, .first, .second").not(this).toggleClass("add-opacity");
});

CODEPEN

希望这能有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接