Mix Blend Mode button hover event issue - html

I'm trying to get a mix-blend-mode working so that a background slide happens. I have put together a jsfiddle of it sort of working.
Problem is, need it to look more like this.
But I do not want to get rid of the skew on it or the slide in from the right. I've tried using the same blend modes as in that example, but no matter what I do, it doesn't maintain the red slide color on hover and white text under the red color. I would like to use pseudo elements only and keep the html to a bare minimum here. I would think this is possible using the pseudo elements, however the blend modes are not cooperating with me and not sure how to get it to look more like the second fiddle. My html is as follows:
View Project
CSS is:
a {
position: relative;
text-decoration: none;
display: inline-block;
padding: 15px 30px;
border: 1px solid #f16251;
background: black;
color: #f16251;
font-size: 30px;
font-family: arial;
mix-blend-mode: normal;
overflow:hidden;
z-index: 1;
}
a:before {
content: '';
position: absolute;
top: 0; bottom: 0; right: 0;
width: 100%; height: 100%;
background: red;
mix-blend-mode: multiply;
transform-origin:0 0 ;
transform:translateX(100%) skewX(30deg);
transition: transform .25s;
z-index: 3;
}
a:hover:before {
transform: translateX(45%) skewX(30deg);
}
a:hover:after {
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
width: 100%;
height: 100%;
background: white;
}
a:after {
content: '';
position: absolute;
top: 0; bottom: 0; right: 0;
width: 100%; height: 100%;
background: white;
mix-blend-mode: difference;
z-index: 2;
}
How do I get the background text to display in white only when the red color slides over that text? My mix-blend-mode code has to be wrong, but it looks like it is possible to do here.

Well, this was fun :)
a {
position: relative;
text-decoration: none;
display: inline-block;
padding: 15px 30px;
border: 1px solid #f16251;
background: white;
color: black;
font-size: 30px;
font-family: arial;
mix-blend-mode: normal;
overflow:hidden;
z-index: 1;
}
a:before {
content: '';
position: absolute;
top: 0; bottom: 0; right: 0;
width: 100%; height: 100%;
background: white;
mix-blend-mode: difference;
transform-origin:0 0 ;
transform:translateX(100%) skewX(30deg);
transition: transform .25s;
z-index: 3;
}
a:hover:before {
transform: translateX(45%) skewX(30deg);
}
a:after{
content: '';
display:block;
top: 0;
left:0;
bottom:0;
right:0;
position: absolute;
z-index: 100;
background: #f16251;
mix-blend-mode: screen;
}
View Project

Related

Why does pseudoelement's background hide parent's?

The parent's background-color and the border-radius is hidden behind the pseudo element. Why is the pseudo element not behind the parent even though it has a z-index of -1?
.btn {
text-decoration: none;
background-color: royalblue;
font-family: sans-serif;
font-weight: bold;
border-radius: 5px;
color: white;
display: inline-block;
padding: 20px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.btn::after {
content: "";
display: inline-block;
width: 100%;
height: 100%;
background-color: cornflowerblue;
position: absolute;
top: 0;
left: 0;
z-index: -1;
}
Download free app
The culprit is the transform property that create a stacking context thus your pseudo element will painted inside this stacking context and will logically be above the background whataver the z-index you will use.
Remove transform to see the difference. I increased the border-radius and changed the color to better see.
.btn {
text-decoration: none;
background-color: red;
font-family: sans-serif;
font-weight: bold;
border-radius: 50px;
color: white;
display: inline-block;
padding: 20px;
position: absolute;
top: 50%;
left: 50%;
}
.btn::after {
content: "";
display: inline-block;
width: 100%;
height: 100%;
background-color: cornflowerblue;
position: absolute;
top: 0;
left: 0;
z-index: -1;
}
Download free app
In case you want the pseudo element to be below the parent you should avoid any properties that create a stacking context or it will be impossible.
Or you consider another pseudo element to create the background layer and you will be able to control the stacking like you want:
.btn {
text-decoration: none;
font-family: sans-serif;
font-weight: bold;
color: white;
padding: 20px;
position: absolute;
transform:translate(-50%,-50%);
top: 50%;
left: 50%;
}
.btn::before,
.btn::after{
content: "";
position: absolute;
top: 0;
left: 0;
right:0;
bottom:0;
z-index:-1;
}
.btn::before {
background-color: cornflowerblue;
}
.btn::after {
background-color: red;
border-radius: 50px;
}
Download free app
Some related questions:
Why elements with z-index can never cover its child?
Is there any way to place z-index according not to its parent element
You just need to add overflow: hidden; to the parent element.
.btn {
text-decoration: none;
background-color: royalblue;
font-family: sans-serif;
font-weight: bold;
border-radius: 5px;
color: white;
display: inline-block;
padding: 20px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
}
.btn::after {
content: "";
display: inline-block;
width: 100%;
height: 100%;
background-color: cornflowerblue;
position: absolute;
top: 0;
left: 0;
z-index: -1;
}
Download free app

prevent hover effect on a tooltip container

I created a tooltip file
[tooltip]:before {
content: attr(tooltip);
position: absolute;
opacity: 0;
right: 0;
top: 110%;
z-index: 9999;
color: #ffffff;
background: #333333;
padding: 10px;
transition: all 0.5s ease;
}
[tooltip]:hover:before {
opacity: 1;
}
[tooltip] {
position: relative;
}
/* other stuff */
#container {
width: 150px;
height: 50px;
background: red;
}
<div id="container" tooltip="Tooltip">Div with tooltip</div>
It works really fine but when hovering over the tooltips position, the hover effect triggers too. The hover effect should just get triggered when hovering over the element the tooltip is attached to.
How can I make the tooltip only appear when hovering the element?
You can remove the pointer-events from the tooltip:
[tooltip]:before {
content: attr(tooltip);
position: absolute;
opacity: 0;
right: 0;
top: 110%;
z-index: 9999;
color: #ffffff;
background: #333333;
padding: 10px;
transition: all 0.5s ease;
pointer-events: none; /* add this */
}
[tooltip]:hover:before {
opacity: 1;
}
[tooltip] {
position: relative;
}
/* other stuff */
#container {
width: 150px;
height: 50px;
background: red;
}
<div id="container" tooltip="Tooltip">Div with tooltip</div>
Add pointer-events: none; to tooltip class.
It disables mouse events (clicking, dragging, hovering, etc.) on elements.
Hope this helps :)
[tooltip]:before {
content: attr(tooltip);
position: absolute;
opacity: 0;
right: 0;
top: 110%;
z-index: 9999;
color: #ffffff;
background: #333333;
padding: 10px;
transition: all 0.5s ease;
pointer-events:none;
}
[tooltip]:hover:before {
opacity: 1;
}
[tooltip] {
position: relative;
}
/* other stuff */
#container {
width: 150px;
height: 50px;
background: red;
}
<div id="container" tooltip="Tooltip">Div with tooltip</div>

CSS border opacity affected by translucent overlay [duplicate]

This question already has answers here:
How do I reduce the opacity of an element's background using CSS?
(29 answers)
Closed 5 years ago.
I have this project:
https://jsfiddle.net/3xw9aqew/
When a user hovers over the grey box, a red overlay appears with a green border/outline. However this border is applied to the overlay which has an opacity value applied to it on hover.
.image-container:hover .overlay {
opacity: 0.3;
}
I want the overlay to be translucent, allowing the image below to be seen, but I want the border around this to be solid so its a standard "green" colour. This is the CSS for the overlay:
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
opacity: 0;
transition: .5s ease;
background-color: red;
border:10px solid green;
box-sizing:border-box;
}
How can i achieve this?
For the intended behaviour, apply the required transparency directly to the background-color property value instead of the containing element as a whole. This can be done by adjusting the rgba value as demonstrated in the embedded code snippet below.
opacity applies to the element as a whole, including its contents,
even though the value is not inherited by child elements. Thus, the
element and its children all have the same opacity relative to the
element's background, even if they have different opacities relative
to one another.
opacity - CSS | MDN
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
opacity: 1;
transition: .5s ease;
background-color: transparent;
border: 10px solid transparent;
box-sizing: border-box;
}
.image-container:hover .overlay {
background-color: rgba(255, 0, 0, 0.3);
border: 10px solid green;
}
Updated JSFiddle
Code Snippet Demonstration:
var imgContainer = document.getElementById("imgContainer");
var lorem = document.querySelector(".hdr-left");
var ipsum = document.querySelector(".hdr-right");
//When clicking on imgContainer toggle between class to change colour and position
imgContainer.addEventListener('click', function() {
lorem.classList.toggle("hdr-color-white");
ipsum.classList.toggle("hdr-color-white");
lorem.classList.toggle('hdr-left-middle');
ipsum.classList.toggle('hdr-right-middle');
});
body {
max-width: 100%;
overflow-x: hidden;
background: yellow;
font-family: sans-serif;
}
.container {
width: 85%;
max-width: 700px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
img {
width: 100%;
max-width: 920px;
}
p {
font-size: 18px;
color: blue;
font-weight: bold
}
p.left {
position: absolute;
top: 0;
bottom: 0px;
right: -32%;
transform: rotate(-90deg);
}
p.right {
position: absolute;
top: 0;
bottom: 0;
left: -32%;
transform: rotate(90deg);
}
h2 {
font-size: 5em;
position: absolute;
text-transform: uppercase;
letter-spacing: 2px;
font-weight: bold;
margin: 0;
z-index: 5;
color: blue;
transition: all 0.5s ease-in-out;
}
.hdr-color-white {
color: white;
}
.hdr-left {
left: -12%;
top: -35%;
}
.hdr-left-middle {
left: 7%;
top: 40%;
}
.hdr-right {
right: -10%;
top: 110%;
}
.hdr-right-middle {
right: 7%;
top: 40%;
}
/*Hovers*/
.container:hover {
cursor: pointer
}
.container:hover>p {
color: red;
}
.container .image-container:hover {}
/*Hovers Ends*/
/*Overlay*/
.image-container {
position: relative;
width: 100%;
padding: 10px;
box-sizing: border-box;
}
.image {
display: block;
width: 100%;
height: auto;
outline: 5px solid blue;
}
.container .image-container:hover>.image {
outline: none;
}
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
opacity: 1;
transition: .5s ease;
background-color: transparent;
border: 10px solid transparent;
box-sizing: border-box;
}
.image-container:hover .overlay {
background-color: rgba(255, 0, 0, 0.3);
border: 10px solid green;
}
/*Overlay Ends*/
<div class="container">
<!--Rotated Text-->
<p class="right">Harolds</p>
<p class="left">Harolds</p>
<!--//Rotated Text-->
<h2 class="hdr-left hdr-color" id="lorem">Lorem</h2>
<div class="image-container" id="imgContainer">
<img src="http://via.placeholder.com/980x550" alt="gucci" class="image">
<!--colour overlay-->
<div class="overlay"></div>
<!--//colour overlay-->
</div>
<h2 class="hdr-right hdr-color" id="ipsum">Ipsum</h2>
</div>

Adding tooltip hover to an image with css

I want to create a tooltip (using css) that appears once the user moves the mouse over an element. I made it work for text, but I have problems making it work for an image.
.container {
position: relative;
width: 15%;
}
.image {
position: relative;
display: inline-block;
width: 100%;
height: auto;
}
.image .tooltiptext2 {
visibility: hidden;
width: 150%;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
position: absolute;
z-index: 1;
top: -8px;
left: 110%;
font-size: 150%;
font-family: Arial;
/* Fade in tooltip - takes 1 second to go from 0% to 100% opac: */
opacity: 0;
transition: opacity 1s;
}
.image .tooltiptext2::after {
content: "";
position: absolute;
top: 50%;
right: 100%;
margin-top: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent black transparent transparent;
}
.image:hover .tooltiptext2 {
visibility: visible;
opacity: 1;
}
You can see what I did in this link:
https://jsfiddle.net/Ruloco/q3e4psh3/
I'll apreciate any help you could give me. Thanks in advance!!
.tooltiptext2 is not a child of .image. Using .image + .tooltiptext2 instead of .image .tooltiptext2 makes the tooltip work.
https://jsfiddle.net/8Lmz2oLj/
The tooltip isn't a child of the image. You need to amend your styles so that the image container is the thing you're listening for a hover on.
.container:hover .tooltiptext2 {
visibility: visible;
opacity: 1;
}
https://jsfiddle.net/q3e4psh3/1/

Positioning :after-pseudo behind text in a link

I was wondering if it's possible to position the z-index of a :after-pseudo element so that it's behind a link's text. For example;
HTML
Here's a link
SCSS
a {
background: #666:
height: 40px;
padding: 0px 20px;
position: relative;
color: #FFF;
&:before {
/* this is occupied */
}
&:after {
content: "";
width: 100%;
height: 100%;
position: absolute;
display: block;
top: 0; left: 0;
background: #000;
}
}
What I'm trying to achieve here is to display the link's text. This is currently not happening because the :after element is overlapping it. I'd like to put the text to the front without using something like a <span> tag. Note: it should overlap its original background, but not the text.
Is there a way to achieve this, or is this simply impossible?
I found a proper solution. I'll use a box-shadow: inset 0 -3.125rem 0 #000; on the element instead. This way I don't have to use the :after element.
Thank you all for the comments.
You just need to add z-index:-1; to the :after-pseudo
a {
background: #666:
height: 40px;
padding: 0px 20px;
position: relative;
color: #FFF;
}
a:after {
content: "";
width: 100%;
height: 100%;
position: absolute;
display: block;
top: 0; left: 0;
background: #000;
z-index:-1;
}
Here's a link
https://jsfiddle.net/d8htv6a9/
It's as easy as setting the z-index: -1; for the :after pseudo-element.
&:after {
content: "";
width: 100%;
height: 100%;
position: absolute;
display: block;
top: 0;
left: 0;
z-index: -1; /* Set this */
background: #000;
}
Here's a JSFiddle: https://jsfiddle.net/thepio/tm9n0x5g/1/
EDIT:
Based on your comment, there is one trick you could use but I don't know if it will go along your animation. You could use a title attribute in the HTML itself and use it as the content of the :after pseudo-element.
a {
position: relative;
background: #666;
height: 40px;
padding: 0px 20px;
position: relative;
color: #FFF;
z-index: 1;
}
a:after {
content: attr(title);
width: 100%;
height: 100%;
position: absolute;
display: block;
top: 0;
left: 0;
background: #000;
color: white;
text-align: center;
}
Here's a link
Then you can perhaps fade it in/out or whatever you prefer.
Here's a new JSFiddle: https://jsfiddle.net/thepio/tm9n0x5g/1/