HTML/CSS transparency through multiple layers - html

Is it possible to create an element, that creates a transparency through x-number of layers 'behind' it?
Example: I have layers with z-indexes 1,2,3,4, whereas 1 is red. I then create a '5th' layer, that I want to cut through the colors of layers 2,3,4 and see the red color through. Is that possible?

You can experiment with the new mix-blend-mode and/or background-blend-mode (if you have background images) which is currently in candidate recommendation for Compositing and blending Level 1.
References: blend modes, and mix-blend-mode.
Be advised though, that this is currently not supported by IE, Edge and Opera.
In the example below, you can see that the top-level div shows red seeping thru from the lowest-level div.
Example Snippet:
.red { background-color: red; }
.blue { background-color: blue; }
.green { background-color: green; }
.yellow { background-color: yellow; }
div {
width: 120px; height: 120px;
position: absolute;
top: 16px; left: 16px;
}
div:nth-of-type(2) { top: 32px; left: 32px; mix-blend-mode: difference; }
div:nth-of-type(3) { top: 48px; left: 48px; mix-blend-mode: overlay;}
div:nth-of-type(4) { top: 64px; left: 64px; mix-blend-mode: multiply; }
<div class="red">1</div>
<div class="blue">2</div>
<div class="green">3</div>
<div class="yellow">4</div>

Transparensy trough multiple elements
Lets try it out:
div {
width: 500px;
height: 300px;
border: 50px solid transparent;
}
.a1 {
background-color: rgba(255, 0, 0, 1);
}
.a2 {
background-color: rgba(255, 165, 0, 0.5);
}
.a3 {
background-color: rgba(0, 128, 0, 0.5);
}
.a4 {
background-color: rgba(0, 0, 255, 0.5);
}
.a5 {
background-color: rgba(238, 130, 238, 0.5);
}
<div class="a1">
<div class="a2">
<div class="a3">
<div class="a4">
<div class="a5">
</div>
</div>
</div>
</div>
</div>
Seems like there is transparency trough all elements.

You can specify the color and transparency of that color in css,
If none of the opacity's combined is 100%, you should be able to get a mix of the colors.
That would look like:
.elclass{
background-color:#f00;
opacity:.2; //20% opacity;
}
if you don't want the opacity of the object to be 20%, but just the background-color use:
.elclass{
background-color:rgba(255,0,0,.2);
}
rgba colors are however not 100% browser safe.

Related

mix-blend-mode on mobile in Chrome and Firefox

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.

Auto resize div to fit two (or more) stacked pictures in it

I have a div with display: inline-block that has two or more IMGs in it. IMGs are "stacked" on top of each other (I also have script that sets z-index when necessary), so I use position: absolute; top: 0; left: 0; for these IMGs. I need to resize containing div to fit the biggest image in it. The problem is, that images are loaded dynamically and have different sizes and I need to resize containing div to fit the biggest one currently in it. When I don not use no position: absolute, containing div resizes automatically to fit the image, but in that case I cannot place images on top of each other.
So, is it possible to achieve this with css only? The goal is to have several images with unknown sizes stacked on top of each other.
Thank you.
(snippet is for illustration only)
window.onload=function()
{
let lastPic=1;
setInterval(function()
{
let pics=document.querySelectorAll(".pic");
pics[lastPic].style.zIndex="";
lastPic=Math.ceil(Math.random()*3);
pics[lastPic].style.zIndex="3";
}, 1000);
};
div#container
{
display: inline-block;
border: 1px solid black;
background: black;
padding: .5em;
}
img.pic
{
position: absolute;
top: 0;
left: 0;
opacity: .9;
}
div#container img:nth-child(1)
{
border: 1px solid #f00;
background: rgba(255,0,0,.5);
}
div#container img:nth-child(2)
{
border: 1px solid #00f;
background: rgba(0,0,255,.5);
}
div#container img:nth-child(3)
{
border: 1px solid #0f0;
background: rgba(0, 255,0,.5);
}
div#container img:nth-child(4)
{
border: 1px solid #0ff;
background: rgba(0,255,255,.5);
}
<!doctype html>
<body>
<div id="container">
<img class="pic" src="https://dom.etogo.net/picsrotate/test/1.png">
<img class="pic" src="https://dom.etogo.net/picsrotate/test/2.png">
<img class="pic" src="https://dom.etogo.net/picsrotate/test/3.png">
<img class="pic" src="https://dom.etogo.net/picsrotate/test/4.png">
</div>
</body>
</html>
Instead of position:absolute, use display:grid (in this case display:inline-grid so it shrink wraps the images) and put all the images in the same row & column.
Note: older versions of Internet Explorer either do not support CSS-Grid or support an older version of the specification and will require specific -ms- grid properties.
div#container {
display: inline-grid;
border: 1px solid black;
padding: 0.5em;
}
img.pic {
grid-row: 1;
grid-column: 1;
opacity: 0.9;
display: block;
}
div#container img:nth-child(1) {
border: 1px solid #f00;
background: rgba(255, 0, 0, 0.5);
}
div#container img:nth-child(2) {
border: 1px solid #00f;
background: rgba(0, 0, 255, 0.5);
}
div#container img:nth-child(3) {
border: 1px solid #0f0;
background: rgba(0, 255, 0, 0.5);
}
div#container img:nth-child(4) {
border: 1px solid #0ff;
background: rgba(0, 255, 255, 0.5);
}
<div id="container">
<img class="pic" src="https://dom.etogo.net/picsrotate/test/1.png">
<img class="pic" src="https://dom.etogo.net/picsrotate/test/2.png">
<img class="pic" src="https://dom.etogo.net/picsrotate/test/3.png">
<img class="pic" src="https://dom.etogo.net/picsrotate/test/4.png">
</div>

Overlapping Polygon's, z-index and before/after

I want to reach this result:
This is what i have atm: http://mijnwebsitebestellen.be/index.php
So i am currently using SVG elements to slice of the images. You can inspect the code in your browser. I can't get the result right because of z-index issues.
Any tips or examples of any sort are appreciated.
You can achieve the same result using pure CSS.
Use a container element for background color and image
Use the pseudo element ::after with a white right border to imitate the right edge
Use some divs of the same class .tile to imitate the stripes with transform: skewX(-10deg); and let them float: right;
Et voilĂ :
.container {
height: 300px;
width: 400px;
background: linear-gradient(rgba(219, 41, 117, 0.6), rgba(219, 41, 117, 0.6)), url(https://i.stack.imgur.com/e11Va.jpg);
background-size: cover;
color: white;
position: relative;
padding-right: 26px;
}
.container::after {
content: "";
position: absolute;
display: block;
right: 0;
bottom: 0;
height: 0;
width: 0;
border: none;
border-left: none;
border-right: 52px solid white;
border-top: 300px solid transparent;
border-bottom: none;
}
.tile {
width: 30px;
height: inherit;
background: rgba(0, 0, 0, 0.6);
border-left: 5px solid white;
transform: skewX(-10deg);
float: right;
}
<div class="container">
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
</div>
Of course you can add content to the container. Just use another div inside the container and give it the apropriate width.

Shape transition with :target

How to :target 1 little red box to do transition into a yellow circle by clicking hyperlink and then make the same little box to transition into a blue square?
Here is my CSS for the little red square:
#Redsquare{
height: 15px;
width: 15px;
background-color: rgb(255,0,0);
position: absolute;
top: 330px;
left: 640px;
transition: all 0.5s linear;
}
Here is the code which targets the #Redsquare into yellow circle.
#Redsquare:target{
height: 300px;
width: 300px;
border-radius: 50%;
background-color: rgb(255,255,0);
top: 200px;
left: 500px;
}
But I want the same little circle to transform into a Bluesquare as well by pressing another button.
This can be done. But it requires nesting in the HTML like shown in the code below. Please do not use this approach if you need the same div to be transformed more than two or three times as the markup will become too messy.
Basically what we are doing here is as follows:
The element that will be transformed is the div with class as box. But how and what it would be transformed to depends on the link that is clicked and the associated target.
When the 1st link is clicked, the outermost div with Yellowcircle is the target. As per the CSS, an element with class box will be transformed to a yellow circle when the target is Yellowcircle.
When the 2nd link is clicked, the Bluesquare div becomes the target and as per CSS in this case, the box should become a blue square.
Finally when the 3rd link is clicked, the target is the general #, so the default .box CSS style will be applied and it goes back to being a red square.
There are other alternatives but they involve JavaScript.
.box {
height: 150px;
width: 150px;
background-color: rgb(255, 0, 0);
transition: all 0.5s linear;
}
#Yellowcircle:target .box {
border-radius: 50%;
background-color: rgb(255, 255, 0);
}
#Bluesquare:target .box {
background-color: rgb(0, 0, 255);
}
/* Just for demo */
a {
position: relative;
margin: 0px 4px;
text-decoration: none;
font-family: Calibri;
font-variant: small-caps;
color: crimson;
}
a:after {
position: absolute;
content: "|";
padding: 0px 4px;
}
a:last-of-type:after {
display: none;
}
<div id='Yellowcircle'>
<div id='Bluesquare'>
<div class='box'>
</div>
</div>
</div>
<a href='#Yellowcircle'>Transform to yellow circle</a>
<a href='#Bluesquare'>Transform to blue square</a>
<a href='#'>Go back to default</a>
This is what I meant by markup becoming messy while needing to transform into more than 3 shapes. Notice how we have to introduce an extra level for each extra shape that is needed.
.box {
height: 150px;
width: 150px;
background-color: rgb(255, 0, 0);
transition: all 0.5s linear;
}
#Yellowcircle:target .box {
border-radius: 50%;
background-color: rgb(255, 255, 0);
}
#Bluesquare:target .box {
background-color: rgb(0, 0, 255);
}
#Greenoval:target .box {
border-radius: 75px 100px;
background-color: rgb(0, 255, 0);
}
/* Just for demo */
a {
position: relative;
margin: 0px 4px;
text-decoration: none;
font-family: Calibri;
font-variant: small-caps;
color: crimson;
}
a:after {
position: absolute;
content: "|";
padding: 0px 4px;
}
a:last-of-type:after {
display: none;
}
<div id='Yellowcircle'>
<div id='Bluesquare'>
<div id='Greenoval'> <!-- notice how for each shape we need to add an extra level -->
<div class='box'>
</div>
</div>
</div>
</div>
<a href='#Yellowcircle'>Transform to yellow circle</a>
<a href='#Bluesquare'>Transform to blue square</a>
<a href='#Greenoval'>Transform to green oval</a>
<a href='#'>Go back to default</a>

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;
}