mix-blend-mode on mobile in Chrome and Firefox - html

I am running Android 10 and Chrome Beta 84.0.4147.89
But the rendering in Chrome and FF of mix-blend-mode seems to be very different. The background of the chat window should be white. When instead it is colorful.
So my question is how can this be fixed for Chrome browser on the
mobile phone?
Also in Chrome on desktop version it seems to run fine as long as
html becomes scrollable.
I am really confused as to what is happening and which fix may be applied to fix at least some of it.
https://jsfiddle.net/f7xbnozt
.chat-container {
position: absolute;
width: 300px;
border: 2px solid black;
border-radius: 8px;
overflow: hidden;
}
.chat {
float: left;
width: 280px;
height: 300px;
padding: 10px 20px;
overflow: auto;
}
.chat-container:after {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
background: linear-gradient(rgb(0, 95, 255) 0%, rgb(146, 0, 255) 50%, rgb(255, 46, 25) 100%);
content: '';
mix-blend-mode: screen;
pointer-events: none;
}
.chat div {
color: white;
background: #1e1e1e;
border-radius: 8px;
padding: 10px 12px;
}
.chat .q {
background: blue;
margin: 6px 0 6px 50px;
}
.chat .a {
background: green;
margin: 6px 50px 6px 0;
}
<div class="chat-container">
<div class="chat">
<div class="q">Chat message...</div>
<div class="q">Chat message...</div>
<div class="a">Chat message...</div>
</div>
</div>

The reason why nothing works is the algorithm.
Transparent background + blue and green + gradient background equals vivid result you see in chrome.
While white background + blue and green + gradient background equals the desired result.
.chat-container {
background-color: #ffffff;
...
}
Curiously, if you copy the original code from jsfiddle to codepen, then nothing will work there either, even in firefox.

Related

Backdrop filter not working with overflow: hidden on parent

I'm trying to use backdrop-filter(blur in this case) on a div only to discover the overflow: hidden property prevents it from applying. The browser is Chrome 78.
Say I've got a div.filter inside a div.block that's wrapper inside a div.container.
div.container > div.block > div.filter
If I apply overflow: hidden to both .container and .block the effect of the filter suddenly disappears. Furthermore, other properties of the .block prevents the filter from being applied.
Seems like the overflow: hidden on .container triggers this erratic behavior. Do you guys have any idea what's going on here?
Demo here: https://codepen.io/marcel_pi/pen/VwYvmGv
Please check the code below:
.container{
overflow: hidden; /* delete to resume normal behavior */
border-radius: 20px;
}
.block{
width: 400px;
height: 400px;
border: 4px solid black;
background: linear-gradient(90deg, transparent 50%, rgba(152,47,138,.5) 50%) antiquewhite;
background-size: 30px;
font-weight: bold;
/* the properties below prevent the filter from being applied once the overflow: hidden is applied to .container */
border-radius: 20px; /* delete to resume normal behavior */
overflow: hidden; /* delete to resume normal behavior */
position: relative; /* delete to resume normal behavior */
}
.filter{
position: absolute;
top: 0;
left: 205px;
width: 230px;
height: 230px;
background: #42add77d;
backdrop-filter: blur(6px); /* the blur filter */
border-radius: 20px;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
If you apply a filter (0px) to the same element that you apply the overflow property to, it will work.
.container{
overflow: hidden; /* delete to resume normal behavior */
border-radius: 20px;
}
.block{
width: 400px;
height: 400px;
border: 4px solid black;
background: linear-gradient(90deg, transparent 50%, rgba(152,47,138,.5) 50%) antiquewhite;
background-size: 30px;
font-weight: bold;
/* the properties below prevent the filter from being applied once the overflow: hidden is applied to .container */
-webkit-filter: blur(0px);
border-radius: 20px; /* delete to resume normal behavior */
overflow: hidden; /* delete to resume normal behavior */
position: relative; /* delete to resume normal behavior */
}
.filter{
position: absolute;
top: 0px;
left: 205px;
width: 230px;
height: 230px;
background: #42add77d;
backdrop-filter: blur(4px);
border-radius: 20px;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
You can test it here as well..
It's a stacking order issue. If you do a simple test of adding, z-index to your block element, you'll see the filter working as expected.
I did a little digging around about overflow and how it's properties affect stacking order, but couldn't find any conclusive documentation.
That said, just add z-index: 1 to your block.
Caveat: This will not work on Firefox unless you set the layout.css.backdrop-filter.enabled preference to true in about:config.
https://caniuse.com/#search=backdrop-filter
.container {
overflow: hidden;
/* delete to resume normal behavior */
border-radius: 20px;
}
.block {
width: 400px;
height: 400px;
border: 4px solid black;
background: linear-gradient(90deg, transparent 50%, rgba(152, 47, 138, .5) 50%) antiquewhite;
background-size: 30px;
font-weight: bold;
border-radius: 20px;
overflow: hidden;
position: relative;
z-index: 1;
}
.filter {
position: absolute;
top: 0px;
left: 205px;
width: 230px;
height: 230px;
background: #42add77d;
backdrop-filter: blur(4px);
border-radius: 20px;
z-index: 10;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
There were some bugs in Chrome with filter / backdrop-filter, border-radius and overflow: hidden:
Asked in May 2013 (Chrome 27): webkit-filter breaks overflow: hidden
Asked in April 2016: Backdrop Filter extends beyond Border Radius.
Should be fixed already: https://bugs.webkit.org/show_bug.cgi?id=142662.
For me, the only property that is not working is .block's overflow: hidden, but you can just remove it, position .filter so that it doesn't overflow and apply its border-radius only to the corners that need it (in this example, border-radius: 0 4px 0 16px):
body {
display: flex;
justify-content: center;
margin: 0;
height: 100vh;
}
.container {
position: relative;
box-sizing: border-box;
flex: 1 1 100%;
margin: 16px;
padding: 16px;
border: 4px solid black;
border-radius: 12px;
overflow: hidden;
}
.block {
position: relative;
box-sizing: border-box;
width: 100%;
height: 100%;
border: 4px solid black;
border-radius: 8px;
background: linear-gradient(90deg, transparent 50%, rgba(152,47,138,.5) 50%) antiquewhite;
background-size: 20px 20px;
font-weight: bold;
/* This is the only one what won't work: */
/* overflow: hidden; */
}
.filter {
position: absolute;
top: 0;
right: 0;
width: 50%;
height: 50%;
background: #42ADD77D;
backdrop-filter: blur(4px);
/*
Add border-radius only top right corner (which should match the parent's border-radius minus its
border-width) and bottom left corner:
*/
border-radius: 0 4px 0 16px;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
I'm using Chrome Version 78.0.3904.108 (Official Build) (64-bit) on Windows 10.

Is there a CSS solution for this design?

Here's my issue:
I have a mockup from a design company that wants a text block with a 'broken' square border behind some big text that looks like this (description: there is a small white frame behind large text that is broken up by the text, and then a smaller text link below):
Image of an element on client's website,
In the design, the text is displayed accross the white square frame. The way I have implemented it right now is to make the big text's background color gray. Because the current image's background is gray the desired effect is achieved.
What is needed is to achieve that effect (of breaking the white frame) REGARDLESS of the appearance of the image. Because right now, this happens:
the gray background of the text appears like a box in front of the image -- it ought to be transparent
To further illustrate, if I set the background-color of the big text to transparent, the whole frame is shown (the desired effect is a broken frame):
background: transparent #1
More info if it helps:
The white frame element is just a div with a white border.
I am not sure exactly what to search for in this case, if there is an appropriate CSS solution (preferrable) or if I need to use SVG or maybe a PNG? Thank you for any help.
As #Temani Afif pointed out in the comments, it's not one box, but two separate shapes in CSS.
I made an example to illustrate this using flexbox.
.page {
background-color: black;
width: 400px;
height: 400px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.box-top {
width: 100px;
height: 10px;
border-color: white;
border-width: 2px;
border-style: solid;
border-bottom: none;
}
.box-bottom {
width: 100px;
height: 30px;
border-color: white;
border-width: 2px;
border-style: solid;
border-top: none;
}
.separator {
color: white;
width: 100%;
margin: 5px 0;
padding: 0;
font-size: 40px;
text-align: center;
}
<div class="page">
<div class="box-top"></div>
<p class="separator">
Headline
</p>
<div class="box-bottom"></div>
</div>
You can make a square element with a border and use a mask on it:
body {
margin: 0;
min-height: 100vh;
background: black;
box-sizing: border-box;
padding-top: 1px;
}
h2.fancy {
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 40px, 100% 40px, 100% 100%, 0 100%);
}
<h2 class=fancy>I'm a fancy title...</h2>
The advantage of this solution is that you can make it scale easily with what might change on various screen sizes. For example, with the title's font-size:
document.querySelector('input.font-size').addEventListener('input', function(e) {
document.querySelector('h2').style.fontSize = e.target.value + 'px';
})
body {
margin: 0;
min-height: 100vh;
background: url(https://picsum.photos/800) center /cover;
box-sizing: border-box;
padding-top: 1px;
}
.overlay {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.5);
}
h2.fancy {
z-index: 1;
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
display: block;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 calc(10px + 1.3em), 100% calc(10px + 1.3em), 100% 100%, 0 100%);
}
input[type=range] {
position: absolute;
bottom: 1rem;
left: 1rem;
z-index: 1;
}
<h2 class=fancy>I'm a fancy title...</h2>
<div class=overlay></div>
<input type=range min=12 max=36 class=font-size>
The disadvantage is that it doesn't work in IE or Edge lower than 18 or in Opera mini. This particular example works in IE 18, though, as it only uses polygon().

CSS background and background-image only shows up on chrome desktop broswer

The image of a background: or background-image: not showing up on website, img src not showing up either.
However, all pictures show up fine only on chrome desktop broswer, but they don’t show up on chrome mobile broswer. Some of the browsers I’ve tested and don’t show the images on my website are: chrome mobile, safari mobile, IE desktop, Microsoft edge desktop.
The entire html css code can be found at the website, is it allowed to include the link in my post?
styles.css
.wrapper {
background: #fff;
margin-top: 20px;
margin-bottom: 20px;
padding: 0 0;
box-shadow: 0px 2px 5px rgba(0,0,0,0.5);
-moz-box-shadow: 0px 2px 5px rgba(0,0,0,0.5);
-webkit-box-shadow: 0px 2px 5px rgba(0,0,0,0.5);
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
background-image: url('./imgSrc/chessbk.png');
background-position: center;
background-size: cover;
/* background-attachment: fixed;*/
/* -o-background-size: cover;*/
/*-moz-background-size: cover;*/
/*-webkit-background-size: cover;*/
}
/* Main page style */
.wrapper .main {
position: relative;
clear: both;
overflow: hidden;
height: auto;
min-height: 100%;
padding: 0 0 0 0;
}
.main {
background-image: linear-gradient(rgba(172, 207, 229, 1), rgba(172, 207, 229, .1));
clear: both;
overflow: hidden;
padding: 0px 0 0 0;
} /*----end main page styles---*/
/* Main page header style */
.header {
position: relative;
z-index: 1;
}
.header .headerIMG {
-moz-border-radius: 8px 8px 0px 0px;
-webkit-border-radius: 8px 8px 0px 0px;
border-radius: 8px 8px 0px 0px;
position: absolute;
z-index: -1;
top: 0;
bottom: 0;
left: 0;
right: 0;
opacity: .3;
width: 100%;
height: 100%;
}
.siteTitle {
padding-top: 25px;
text-align: center;
margin: 0 auto;
width: 940px;
position: relative;
color: floralwhite;
padding-bottom: 25px;
} /*-----end header styles----*/
/* Navigation styles */
#access {
background: url('./imgSrc/access_bg.png');
/*
opacity: 0.8;
filter:alpha(opacity=80);
*/
display: block;
float: left;
margin: 0 auto;
width: 940px;
font-weight:bold;
border-top:1px solid rgba(0,0,0,0.5);
border-bottom:1px solid rgba(0,0,0,1);
}
Case of using background: HTML
<body>
<div class="wrapper">
<div class="header">
<div class="headerIMG" style="background: url(imgSrc/planet.jpg) no-repeat center bottom;">
</div>
<div class="siteTitle">
<h1> Rocky Mountain Chess Rating System</h1>
<h2> Idaho Chess Association Database</h2>
</div>
Further down in the html file above:
<div class="main">
<div class="icaImg">
<img src="imgSrc/icaLogo.png">
</div>
<div id="contentGameEnter">
<div class="enterGame">
Just tested it, this is an update edit, images appear on safari desktop and Firefox desktop. So the browsers which don’t work are mobile browsers and IE desktop, Microsoft edge desktop
Once you get https, I used letsencrypt to get free sll certificate, it solves the problem. In other words, getting https has now allowed the images to show up on chrome mobile, safari mobile, (chrome desktop, but they already showed here), IE desktop. Overall, get https it solved this problem for me.

Creating a “flat long shadow” for text in CSS with less CSS

Note: This question is similar to this question; however, it is different and thus is being asked as a separate question to the one just linked.
I am trying to create a flat long shadow in CSS for the text in a logo. The original way I found to do it is based on Matt Lambert's tutorial. The way Matt proposes to do it would require a lot of CSS (although, kudos to him, it does work and goodness knows I didn't figure that out). So thus that led me to ask for a way to do that with less CSS. #vals figured out how to do that with this.
Now I'm attempting to make a flat-long-shadow (does anyone have a shorter abbreviation for this? how about the acronym: "FLS?") for the text of a logo (i.e. this); however, it isn't going so well...
As you can see from this fiddle I made, I sort of combine the two techniques... but, while it's not atrocious, it doesn't work perfectly...
Here is the same fiddle in a snippet:
/* shadow color: #2d5986 */
html, body {
height: 100%;
}
body {
display: flex;
flex-flow: column wrap;
overflow: hidden;
}
div {
min-height: 128px;
min-width: 128px;
background-color: #369;
color: white;
font-size: 4em;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
span {
/* background-color: #47a; */
position: relative;
text-align: center;
text-shadow: #2d5986 1px 1px,
#2d5986 2px 2px,
#2d5986 3px 3px,
#2d5986 4px 4px,
#2d5986 5px 5px,
#2d5986 6px 6px,
#2d5986 7px 7px,
#2d5986 8px 8px,
#2d5986 9px 9px,
#2d5986 10px 10px,
#2d5986 11px 11px,
#2d5986 12px 12px,
#2d5986 13px 13px,
#2d5986 14px 14px;
}
.shadow:before, .shadow:after {
content: "";
position: absolute;
right: 0px;
bottom: 15px;
z-index: 1;
transform-origin: bottom right;
}
.shadow:before {
height: 40px; /* increased height */
width: 100%;
left: 0px;
transform: skewX(45deg);
box-shadow: 1px 40px 0px 0px #2d5986; /* 1px in x direction to avoid small gap between shadows */
}
/* .shadow:after {
width: 10px; increased width
height: 100%;
top: 25px;
transform: skewY(45deg);
box-shadow: 10px 0px #2d5986;
} */
<div>
<span class="shadow">
A
</span>
</div>
<div>
<span class="shadow">
a
</span>
<span class="shadow">
b
</span>
</div>
<div>
<span class="shadow">
A B
</span>
</div>
<div>
<span class="shadow">
A B C
</span>
</div>
The main problem is the fact that we are now working with text-shadow instead of box-shadow, and as such the :before and :after pseudo classes don't work (although I attempted to make them work by attaching them to the <span>... and then made the width: 100%).
If there was a way to set the width and height of the text-shadow itself (which is achieved on a box-shadow by using the :before and :after pseudo classes), I feel this would be a piece of cake; however, all my research has not found how to do this for a text-shadow.
Does anyone know a way to make a flat long shadow for text with minimal CSS - potentially by somehow changing the width and height of the text-shadow?
Thank you.
Though this is no css-only answer, you might give it a try.
Basically, you create the according css in the browser via a short javascript snippet. The upside is, that it makes you very flexible - changing only two parameters instead of several tens of lines of css.
function addDropShadow(element,width,color){
let css = "";
for (var i = 1;i<width;i++){
css += `${color} ${i}px ${i}px,`;
}
css += `${color} ${width}px ${width}px`;
element && (element.style.textShadow = css);
}
let element = document.querySelector(".icon");
let color = "rgb(18, 128, 106)";
addDropShadow(element,15,color);
.container { padding: 50px; background: rgb(34,45,58); } .icon { font-family: "Helvetica Neue", helvetica, arial, sans-serif; font-weight: bold; color: #fff; background-color: rgb(22, 160, 133); height: 150px;width: 150px; font-size: 75px;line-height: 150px; text-align: center; display: block; overflow: hidden; }
<div class="container"><div class="icon">YO</div></div>
I don't think there is a good CSS only approach.
The only posibility that I can think of is creating pseudos with the same text as the base, and use to reduce the amount of shadows to one third:
Notice that the pseudo itself counts as a shadow because it has the color changed to the color of the shadow
.sample {
font-size: 70px;
position: relative;
text-shadow: 1px 1px red, 2px 2px red, 3px 3px red, 4px 4px red, 5px 5px red,
6px 6px red, 7px 7px red, 8px 8px red, 9px 9px red;
}
.sample:after, .sample:before {
content: attr(data-text);
z-index: -1;
color: red;
position: absolute;
}
.sample:after {
left: 10px;
top: 10px;
}
.sample:before {
left: 20px;
top: 20px;
}
<div class="sample" data-text="Sample">Sample</div>

CSS transparency issues in nested elements

hey there i wonder if any of you have come across a similar issue? i am working on an ad section of the webpage and its got a really cool background that i would like to carry on into sections of the elements so i have a box that hold a box for a rss feed into updates made on the website and then i have a box for adverts. here is my html:
<div class="side">
<div id="ad">
bla
</div>
<div id="rss_news">
double bla
</div>
</div>
and the css:
.side {
float: left;
background-color: black;
width: 300px;
min-height: 710px;
padding: 0 0 0 0px;
margin-top: 25px;
border: 1px solid white;
border-radius: 8px 8px 8px 8px;
opacity: 0.3;
}
#ad {
border: 1px solid blue;
height: 320px;
max-height: 350px;
margin: 15px;
opacity: 1;
}
#rss_news {
border: 1px solid yellow;
height: 320px;
max-height: 350px;
margin: 15px;
opacity: 1;
}
as you can see and as i was anticipating the side class immits his attributes on the ones nested within him. is there a way that i could somehow tell the other id tags to ignore that opacity?
thanks in advance :D
There is no way to make descendants ignore the parent's opacity.
You can use rgba/hsla colors to get a partially transparent background, without affecting the children's visibility. Example:
.side {
background-color: rgba(0,0,0, 0.3);
}
Demo: http://jsfiddle.net/ywQy5/
See also:
MDN: hsla colors
MDN: rgba colors
You can use css3 rgba property for this & for IE you can use IE filter.Write like this:
.side{
background-color: rgba(0,0,0, 0.5);
background: transparent;
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#7F000000,endColorstr=#7F000000); /* IE*/
zoom: 1;
}