CSS mix-blend-mode: Browser/Display Inconsistency - css

I utilize the mix-blend-mode property on my portfolio site to achieve a fun effect with the landing page headline. I am using the multiply value to blend 3 layers that are cyan, magenta, and yellow. Where they overlap I would expect the result to be black.
That used to be the case. I've noticed recently, depending on the browser and display I view it on, that is not the case.
I put together a simple code pen to demonstrate this.
HTML
<main class="wrap">
<div class="color-wrap">
<div class="c"></div>
<div class="m"></div>
<div class="y"></div>
</div>
</main>
CSS
.wrap {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
}
.color-wrap {
width: 300px;
height: 300px;
border: 1px solid #000;
position: relative;
background-blend-mode: multiply;
}
.c, .y, .m {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
mix-blend-mode: multiply;
}
.c {
background-color: cyan;
top: 100px;
left:100px;
}
.m {
background-color: magenta;
top: -100px;
left:-100px;
}
.y {
background-color: yellow;
}
With Chrome and Safari, on my MacBook Pro display, the result of the 3 blended colors is a muddy purple. If I view it on my external monitor the result is closer to black. On Firefox, regardless of the display, the result is pure black. I'm attaching screenshots.
I don't like the muddy purplish color that I see in certain cases and wish this was more consistent. Any thoughts or insights?
MacBook Air display, Chrome Browser
External monitor, Chrome Browser
MacBook Air display, Firefox Browser

Related

CSS transform showing background color in border

I have two <div> elements. When the user hovers, a transformation of transform: translateY(x, y); is applied. However, a black border also somehow appears (there should only be a red border) when the user hovers.
Resolution: 1920*1080
.link {
display: block;
height: 350px;
width: 200px;
background: black;
border: 1px solid red;
}
.element {
background: white;
height: 100%;
width: 100%;
}
.link:hover {
transform: translateY(-5px)
}
<div class="link">
<div class="element">
test
</div>
</div>
I am not absolutely sure I am understanding the problem, but one way to get rid of the black on hover is to set the background to transparent then. See snippet below.
Note that trying to get exact alignment of very thin borders/lines (1 CSSpx in this case) is not always possible given modern displays use several 'physical' pixels for one CSS pixel. Sometimes zooming in/out shows/doesn't show 1 (display) pixel 'left behind'. And I have seen this in this case, so certain display sizes may show the black.
.link {
display: block;
height: 350px;
width: 200px;
background: black;
border: 1px solid red;
}
.element {
background: white;
height: 100%;
width: 100%;
}
.link:hover {
transform: translateY(-5px);
background: transparent;
}
<div class="link">
<div class="element">
test
</div>
</div>

Rounded, transparent cutout area and background image, with CSS?

I am trying to code the attached layout (needs to be responsive and not use JavaScript if possible). I want to support IE8, or if not, a gracefully degrading solution would be great.
I found ways to make the semicircle cutout using pseudo-elements and border-radius, but the background image of the previous div needs to show through and I can't figure out how to do it. Please help!! I have highlighted the area covered by the background image, in case it is not clear. Here is the layout
I got this far: https://jsfiddle.net/dcwoLb7f/
HTML:
<div id="first"><p>IMAGE CREDIT: WIKIPEDIA</p></div>
<div id="second"></div>
CSS:
#first {
background-image: url('http://upload.wikimedia.org/wikipedia/commons/5/5a/VirtuellesStudio_Greenbox.jpg');
background-size: cover;
position: relative;
}
p {
color: white;
text-align: center;
margin: auto;
font-size: 40px;
}
#first, #second {
width: 100%;
height: 200px;
}
#second {
background-color: blue;
}
#first:after {
content: '';
background-color: white;
height: 40px;
width: 40px;
border-radius: 100%;
position: absolute;
bottom: -20px;
left: 50%;
transform: translate(-50%, 0);
}

Layout of pseudoelements inside a button in Opera

I'm trying to use the :before and :after pseudoelements to add an icon to <button/> element. While it works fine for Chrome/Firefox/IE it breaks on Opera because its layout mechanism seems to be different. After some testing, I reduced it down to the following test case:
<style>
.foo {
display: block;
position: relative;
background: cyan;
width: 100px;
height: 100px;
padding: 0;
margin: 0;
border: 1px solid black;
}
.foo:after {
background: lime;
border: 10px solid yellow;
content: " ";
position: absolute;
left: 25px;
top: 25px;
width: 50px;
height: 50px;
}
</style>
<div class="foo"> </div>
<button class="foo"> </button>
Here, two different elements are styled with the same class. One would expect them to show approximately the same layout (and indeed it is the case in non-Opera browsers), but on Opera the layouts are drastically different:
This was tested using Chrome 33.0 and Opera 12.16 on Windows 7. It doesn't affect other subelements though, only the pseudoelements.
Is there a way to mitigate this problem without using "real" subelements?
(I should note that even after making the two elements have completely identical computed styles in Dragonfly, the problem still occurs.)

CSS mask max-height bug

So my problem is with using a css mask to hide a position: fixed; item. Reason being because apparently overflow: hidden; doesn't work. So this actually works swimmingly in all the browsers I've tested it in UNTIL the height of the div containing the mask reaches a specific, seemingly arbitrary, height. ( 1280px on iPad, 2000px in desktop Safari )
I'm totally stumped on this and haven't found anyone with any documentation on this issue. Has anyone worked with css masks at all to maybe have some clues as to why this is the case?
Here's a screencast demoing the bug and the code used to generate it.
https://www.dropbox.com/s/bxzsmkqgll1yeix/Screeny%20Video%20Feb%2010%2C%202014%2C%209.18.28%20PM.mov
And here's a zip with the code used in that demo.
http://cl.ly/Tqy7
Any ideas or proposed solutions?
--- HTML ---
<div class="attn hairline"></div>
<div class="shadow"></div>
<div id="home">
<div class="attn blur"></div>
<div id="content">
<p>Hey, here is some awesome content, stuff you will definitely want to read.</p>
</div>
</div>
--- CSS ---
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
width: 100%;
text-align: center;
background-color: #f0f0f0;
}
.attn {
position: fixed;
width: 80%;
height: 100%;
left: 50%;
margin-left: -40%;
background: no-repeat center;
background-size: 100% auto;
}
.hairline {
background-image: url(../img/attn.svg);
}
.blur {
background-image: url(../img/blur.png);
}
.shadow {
position: relative;
height: 20px;
margin-bottom: -20px;
box-shadow: 0px -3px 6px rgba(0,0,0,.1);
top: 100%;
}
#home {
position: relative;
top: 100%;
background: #fff;
mask: url(../img/mask.svg);
-webkit-mask: url(../img/mask.svg);
-o-mask: url(../img/mask.svg);
-ms-mask: url(../img/mask.svg);
/* 1281px will kill the mask on iPad, 2001px will kill it on the desktop */
height: 1280px;
}
#content {
padding: 10% 5%;
}
What I ended up doing was setting a max-height attribute on the masked element until that element got to the top of the browser window. I had the fuzzy image text disappearing at this point anyway so it was a good time to, once the image was gone, remove that max-height attribute. Works great, though I'd still love to solve the original problem someday. I'm guessing its a browser quirk though seeing as how it was so arbitrarily consistent.

Adding colored bar to image with CSS

I have the css code below along with an image to show it's output. I need help though 2 things.
This code works pretty good to show the username on the photo, however I noticed today while using chrome all day often when I would click a link that would take me to the page that has images with this code, it would not show the name on the image, it would just show the name below the image and the transparent black div would not be visible at all and the name would not even be on the image, I would then refresh the page and it would work fine, what could cause this, this was while my PC was acting like it was short on memory, could that be part of the issue?
I would like to make a bar show at
the top of the image that is the
width of the image and like maybe
2-3 pixels tall and have a
background color of like blue. What
I am wanting to accomplish is for
femail users there will be a pink
bar over there image and a different
color for males. Can someone who
knows css help me modify this to do
that the best please
<style type="text/css">
div.imageSub { position: relative; }
div.imageSub img { z-index: 1; }
div.imageSub div {
position: absolute;
left: 0px;
right: 0px;
bottom: 0;
padding: 5px;
height: 5px;
line-height: 4px;
text-align: center;
overflow: hidden;
}
div.imageSub div.blackbg {
z-index: 2;
background-color: #000;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
filter: alpha(opacity=70);
opacity: 0.5;
}
div.imageSub div.label {
z-index: 3;
color: white;
}
</style>
<div class="imageSub" style="width: 90px;"> <!-- Put Your Image Width -->
<img src="http://cache2.mycrib.net/images/image_group66/0/43/t_6871399b0962b5fb4e29ce477541e165950078.jpg" alt="Something" width="90"/>
<div class="blackbg"></div>
<div class="label">Sara</div>
</div>
Since I've written this code for you, seems logical that I also try to fix it...
It seems that Chrome is struggling since it doesn't know the height of the element. Let's use margins instead of positioning
Also, since you are using a set height, you could drop positioning all together and use the following CSS (In which case you shouldn't need the above code):
div.imageSub img { z-index: 1; margin: 0; display: block; }
div.imageSub div {
position: relative;
margin: -15px 0 0;
padding: 5px;
height: 5px;
line-height: 4px;
text-align: center;
overflow: hidden;
}
div.imageSub div.blackbg {
z-index: 2;
background-color: #000;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
filter: alpha(opacity=70);
opacity: 0.5;
}
div.imageSub div.label {
z-index: 3;
color: white;
}
EDIT: You've asked for a top colored bar for the gender. You can use the following HTML:
<div class="imageSub" style="width: 90px;"> <!-- Put Your Image Width -->
<img class="female" src="http://cache2.mycrib.net/images/image_group66/0/43/t_6871399b0962b5fb4e29ce477541e165950078.jpg" alt="Something" width="90"/>
<div class="blackbg"></div>
<div class="label">Sara</div>
</div>
With the following CSS:
div.imageSub img.female { border-top: 10px solid red; }
div.imageSub img.male { border-top: 10px solid blue; }

Resources