I'm currently learning CSS, and I'm experimenting with the 'mix-blend-mode' property. I'm attempting to create a navbar that includes a logo (<h1> element) and a 'toggle-button', which should invert what's underneath it with 'difference' value. However, I'm encountering issues as it doesn't seem to work as expected. Interestingly, I have managed to make it work on other elements such as different images and even a custom cursor. I suspect that I might not be comprehending this property accurately, but I have been unable to locate any resources that provide a clearer explanation than what I currently understand ...
Here is my html :
<body>
<div class="cursor">
<div class="cursor-small">
</div>
<div class="cursor-big"></div>
</div>
<nav>
<div class="logo hoverable">
<h1>LOGO</h1>
</div>
<div class="menu-toggle hoverable">
<div></div>
<div></div>
<div></div>
</div>
</nav>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="app.js"></script>
</body>
and my css :
html {
cursor: none;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: serif;
color: white;
background-color: #530101;
}
cursor :
.cursor {
pointer-events: none;
z-index: 9999;
display: block;
height: 0;
}
.cursor .cursor__small {
background-color: #fff;
width: 10px;
height: 10px;
border-radius: 50%;
position: relative;
z-index: 10001;
/* background-color: blue; */
mix-blend-mode: difference;
}
.cursor .cursor__big {
background-color: #fff;
width: 20px;
height: 20px;
border-radius: 50%;
/* background-color: red; */
mix-blend-mode: difference;
position: relative;
z-index: 10001;
}
nav :
nav {
position: sticky;
top: 0;
left: 0;
height: var(--nav-height);
width: 100%;
padding: 0 2rem;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 10;
}
nav .logo h1 {
position: relative;
z-index: 1000;
font-size: 60px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.2rem;
mix-blend-mode: difference;
}
nav .menu-toggle {
width: calc(40px + 1rem);
cursor: pointer;
}
nav .menu-toggle div {
position: relative;
z-index: 10;
width: 2.5rem;
height: 0.25rem;
margin: 0.5rem auto;
transition: all 75ms ease-in-out;
mix-blend-mode: difference;
}
nav .menu-toggle.toggled div:first-child {
--translate-x: -0.5rem;
transform: translate(var(--translate-x), var(--translate-y));
}
nav .menu-toggle.toggled div:last-child {
--translate-x: 0.5rem;
transform: translate(var(--translate-x), var(--translate-y));
}
nav .menu-toggle:hover div:first-child {
--translate-y: -0.25rem;
transform: translate(var(--translate-x), var(--translate-y));
}
nav .menu-toggle:hover div:last-child {
--translate-y: 0.25rem;
transform: translate(var(--translate-x), var(--translate-y));
}
I also tried backdrop-filter: invert(1) on my button divs but when I apply mix-blend-mode to the logo, the button disappear. it's my first post here so I hope that it's clear (please excuse the awful css)
You have to treat mix-blend-mode
elements like layers.
In your case, you're trying to apply an operation like difference
to your logo but the problem is your logo is on top of an element, in this case the nav
, that has no background color and thus nothing to calculate.
I changed the color of the logo to blue just to make it obvious as white is barely noticeable in this case.
https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
html {
cursor: none;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: serif;
color: white;
background-color: #530101;
}
.cursor {
pointer-events: none;
z-index: 9999;
display: block;
height: 0;
}
.cursor .cursor__small {
background-color: #fff;
width: 10px;
height: 10px;
border-radius: 50%;
position: relative;
z-index: 10001;
/* background-color: blue; */
mix-blend-mode: difference;
}
.cursor .cursor__big {
background-color: #fff;
width: 20px;
height: 20px;
border-radius: 50%;
/* background-color: red; */
mix-blend-mode: difference;
position: relative;
z-index: 10001;
}
nav {
position: sticky;
top: 0;
left: 0;
height: var(--nav-height);
width: 100%;
padding: 0 2rem;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 10;
background-color: #530101;
}
nav .logo h1 {
position: relative;
z-index: 1000;
font-size: 60px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.2rem;
color: blue;
mix-blend-mode: difference;
}
.difference {
mix-blend-mode: difference;
}
nav .menu-toggle {
width: calc(40px + 1rem);
cursor: pointer;
}
nav .menu-toggle div {
position: relative;
z-index: 10;
width: 2.5rem;
height: 0.25rem;
margin: 0.5rem auto;
transition: all 75ms ease-in-out;
mix-blend-mode: difference;
}
nav .menu-toggle.toggled div:first-child {
--translate-x: -0.5rem;
transform: translate(var(--translate-x), var(--translate-y));
}
nav .menu-toggle.toggled div:last-child {
--translate-x: 0.5rem;
transform: translate(var(--translate-x), var(--translate-y));
}
nav .menu-toggle:hover div:first-child {
--translate-y: -0.25rem;
transform: translate(var(--translate-x), var(--translate-y));
}
nav .menu-toggle:hover div:last-child {
--translate-y: 0.25rem;
transform: translate(var(--translate-x), var(--translate-y));
}
<body>
<div class="cursor">
<div class="cursor-small">
</div>
<div class="cursor-big"></div>
</div>
<nav>
<div class="logo hoverable">
<h1>LOGO</h1>
</div>
<div class="menu-toggle hoverable">
<div></div>
<div></div>
<div></div>
</div>
</nav>
</body>