如何处理两个重叠 div 的“双重不透明度”

Posted

技术标签:

【中文标题】如何处理两个重叠 div 的“双重不透明度”【英文标题】:how to handle 'double opacity' of two overlapping divs 【发布时间】:2012-02-03 12:49:54 【问题描述】:

我有两个 div,不透明度均为 0.6。我需要它们重叠但保留它们的不透明度,而不是创建新的组合不透明度级别。我不能使用图像。

编辑——这个小圆圈应该有一个画布元素。不确定伪元素是否是最好的解决方案。

有没有办法用 CSS 做到这一点,还是我应该只使用画布?

例子-

http://dabblet.com/gist/1566209

html

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

CSS:

/**
 * Double Opacity
 */
bodybackground: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;

【问题讨论】:

您的意思是希望重叠区域的不透明度也具有 0.6 的表观值? 我不确定这是否可能。这是不透明度的自然功能。 - 至少无论如何都不会使用 CSS... 这是一个很棒的问题!非常期待解决方案(=hack)(如果有的话)。 旁注:Dabblet 看起来作为 jsFiddle 的替代品非常酷。太糟糕了,它在 Safari 中根本不起作用......在控制台中无限加载和语法错误。 Dabblet 中的编辑器太可怕了。 jsFiddle 的编辑器几乎完美。 【参考方案1】:

总结:


根据需要,这可能会很棘手,但基本方法非常简单。


这种方法和我最初的想法有点不同……但结果是一样的。

    我为圆圈制作了黑色/透明图案并将其设置为 :before。 然后圆被变换rotate(180deg) 并移动以适应 &lt;div&gt; 的一角。 然后我将那个圈子的opacity设置为0.6&lt;div&gt; 本身不受opacity 的影响。 接下来我添加了:after 元素并将图像设置为background (如果需要可以通过js控制) 我为图像添加了一些效果(border-radiusbox-shadowborder) 来展示这个元素是多么容易和独立 受控。 我使用了较浅的背景并将opacity 设置为0.3 以显示 结果

这是小提琴:http://jsfiddle.net/pixelass/nPjQh/4/

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

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

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

位置=绝对;

top = circleHeight / -2;

左 = circleHeight / -2; //(左=上)

旋转 = 180 度;

不透明度 = valueAofBackground;

bgColor = valueRGBofBackground;

#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/

查看下面代码中的 cmets

#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/


管理圆的偏移量


看看这些处理圆偏移的例子(NOT USING PSEUDEO-ELEMENTS

OP 代码的 1:1 副本(15px 偏移):http://jsfiddle.net/pixelass/nPjQh/12/

偏移量小很多(5px):http://jsfiddle.net/pixelass/nPjQh/13/

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

偏移是如何工作的?

控制background-sizetopleft

规则

顶部 = 左侧;

背景尺寸 = elementHeight * 2 + top * 2;

看花(也只有一个&lt;div&gt;带伪元素) background-size 比圆圈大。这会在底部产生绿叶

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


当前问题


看到这个小提琴:http://jsfiddle.net/pixelass/nPjQh/16/

如果不使用文章顶部示例中所示的其他图层,则内容将是透明的。因此,如果您只需要圆圈内的图像,上述示例就可以正常工作。

如何解决这个问题

如果您需要画布或圆圈内的另一个 div,您必须将圆圈放在 div 上,并将所需的 div 放在圆圈上

看到这个小提琴:http://jsfiddle.net/pixelass/nPjQh/17/

稍微改变一下,它就会正常工作。从小提琴中获取代码


不同的形状/高级样式


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

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

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

查看盒子阴影的小提琴:http://jsfiddle.net/pixelass/nPjQh/21/


为圆圈添加边框


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


更多示例:


div 周围的四个圆圈

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>

使用此技术制作工具提示

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>

【讨论】:

重叠区域永远不会改变。我不明白背景渐变是如何工作的。如果可以,请发布示例。 我大约 2 小时后到家。如果位置是静态的,那是一个非常简单的 hack.. 我可能有点密集,但在您当前发布的所有小提琴示例(4、5、6)中,我没有看到一个真正重新创建和解决 OP 的重叠不透明度问题的创造他试图避免的较暗区域的颜色。 目标是制作一个半透明的盒子,左上角有一个扩展的圆角……对吧?嗯,这正是这些例子所展示的。 @pixelass 啊,是的,opacity!错过了一个=)我敢说它很棒。这个答案怎么只有2个赞成票?你疯狂的例子太棒了!我完全在某个地方使用它。【参考方案2】:

我认为唯一的方法是单独做不透明度,

例如 http://dabblet.com/gist/1566278

【讨论】:

是的,但这也会修改文本的不透明度。 @roXon 是的,但很容易解决。比使用 OP 建议的画布更容易...... 是的。 +1(我认为唯一的)合理答案(使用两个 div!)。 很遗憾#foo div 中有很多内容无法透明。 看我上面的答案...根据浏览器,这可以很容易地用 CSS3 和 js 完成【参考方案3】:

这个怎么样:http://jsfiddle.net/rudiedirkx/TqRCw/

(Dabble 的编辑很烂!!)

遗憾的是,仅使用伪元素无法做到这一点 =(

只能使用伪元素来完成!请参阅 pixelass 的回答。不过 CSS3 是必需的。

【讨论】:

这可以轻松完成,无需任何特殊标记或伪元素...相信我,这真的很简单...一两个小时后回家...然后我会给出这个问题的正确答案... 对不起......当然不是没有伪元素......因为它是为了创建圆圈。我的想法是结合使用背景渐变、背景位置和背景大小。 +1--我刚刚看了你的回答,发现它和我自己的几乎一模一样(只是你发的比我早得多,而且你的更优雅一些)。 效果不错,但我需要在那个小圆圈内放一个图像或画布元素。 您可以添加背景,但不能添加伪元素内的元素。显然你可以用真实元素替换伪元素,但我喜欢语义,这不是。【参考方案4】:

修改后的答案

This fiddle 与 IE9 兼容,并解决了我原始答案中所需的背景重复问题。它确实使用伪元素来生成圆。这个解决方案衍生了pixelass的“pacman”想法,只是不使用较新的背景渐变css来生成,而是使用较旧的(和little used or understood)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);

原答案

您可以这样做 (see fiddle)。它推动下面的圆圈并“覆盖”与伪元素重叠的部分以重新建立主体的背景颜色:

bodybackground: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--我已经解决了圆偏离中心的问题。 OP 应该提到他正在寻找与 iPhone 兼容的方式。即使您的版本支持 IE9,但它与 iPhone 不兼容(我的也不兼容)。你的版本有微小的重叠,我的有微小的差距......无论如何 +1 以支持 IE9 是的,知道有关 iPhone 的信息会很好。我不确定您上次查看的是哪个版本,但我没有看到与最新版本有微小的重叠。【参考方案5】:

我创建了一个 Q/A 来处理这种情况以及此类重叠元素的“悬停”。

Overlapped elements with opacity and handling the 'hover' on those.

解决方案基本上是在父级别设置不透明度,而不是直接在子元素上设置,并在悬停时使用 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

希望这会有所帮助。

【讨论】:

以上是关于如何处理两个重叠 div 的“双重不透明度”的主要内容,如果未能解决你的问题,请参考以下文章

如何处理多个重叠数据集?

如何处理Swift 4中的按钮重叠?

PHP/GD:如何处理 jpg 透明度?

如何处理 UITabBar 上的长名称 [重复]

如何处理 RobotFramework 中 div 类的切换窗口

如何处理隐藏 div 内的谷歌地图(更新图片)