Is there a CSS property to invert the font-color
depending on the background-color
like this picture?
There is a CSS property called mix-blend-mode, but it's not supported by IE. I recommend using pseudo elements. If you like to support IE6 and IE7 you can also use two DIVs instead of pseudo elements.
.inverted-bar {
position: relative;
}
.inverted-bar:before,
.inverted-bar:after {
padding: 10px 0;
text-indent: 10px;
position: absolute;
white-space: nowrap;
overflow: hidden;
content: attr(data-content);
}
.inverted-bar:before {
background-color: aqua;
color: red;
width: 100%;
}
.inverted-bar:after {
background-color: red;
color: aqua;
width: 20%;
}
<div class="inverted-bar" data-content="Lorem ipsum dolor sit amet"></div>
mix-blend-mode
but the included code doesn't have that property set anywhere. –
Shamanism mix-blend-mode
. This answer is valid but this answer should be accepted/top answer. –
Spermatid Use mix-blend-mode
.
div {
position:absolute;
height:200px
}
/* A white bottom layer */
#whitebg {
background: white;
width:400px;
z-index:1
}
/* A black layer on top of the white bottom layer */
#blackbg {
background: black;
width:100px;
z-index:2
}
/* Some white text on top with blend-mode set to 'difference' */
span {
position:absolute;
font-family: Arial, Helvetica;
font-size: 100px;
mix-blend-mode: difference;
color: white;
z-index: 3
}
/* A red DIV over the scene with the blend-mode set to 'screen' */
#makered {
background-color: red;
mix-blend-mode: screen;
width:400px;
z-index:4
}
<div id="whitebg"></div>
<div id="blackbg"></div>
<div id="makered"></div>
<span>test</span>
I know this is an old question, but I wanted to add another solution I've been using before I learned of mix-blend-mode
.
The idea is to have the information duplicated in two layers, a back and a front, where the back and front have different background and text colors. These are identical in dimension and text. In between, I use a clipping box div
to crop the front (top) layer to the desired width, showing the front layer where it is not clipped, and revealing the back layer outside of the clipping window.
This is similar to the "Two div" solution in the accepted answer, but uses the extra clipping box. What's advantageous in this solution is the easy centering of text if desired, and simple, direct selection of the colors.
// Set *front* width to *back* width
// Do this after DOM is ready
$('#front').width($('#back').width())
// Based upon an event that determines a content change
// you can set the text as in the below example
percent_complete = 45 // obtain this value from somewhere; 45 is just a test
$('#front').text(percent_complete.toString() + '% complete')
$('#back span').text($('#front').text())
bb_width = (percent_complete * $('#back').width())/100
$('#boundbox').css('width', bb_width.toString())
.progress {
display: block;
margin: 0;
/* Choose desired padding/height in coordination with font size */
padding: 10px;
height: 28px;
}
#back {
position: relative;
/* Choose a border to your liking, or none */
border: 1px solid lightgray;
/* Choose your desired text attributes */
text-align: center;
font-family: Calibri, "Sans Serif";
font-size: 16pt;
/* Set the desired width of the whole progress bar */
width: 75%;
/* Choose the desired background and text color */
background-color: white;
color: black;
}
#front {
position: absolute;
left: 0;
top: 0;
/* Choose the desired background and text colors */
background-color: navy;
color: white;
}
#boundbox {
position: absolute;
left: 0;
top: 0;
overflow: hidden;
}
html
<div class='progress' id='back'>
<span></span>
<div class='progress' id='boundbox'>
<div class='progress' id='front'>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
I use jQuery to programmatically set the percent progress and make sure that the width of the front matches that of the back, and that they have identical text. This can also easily be done with pure Javascript.
And here's a fiddle: Progress bar.
I tested this in Chrome, Firefox, Microsoft Edge, and IE version 11.
I've seen that this is quite an old question, but having found myself with the same problem I came up with a solution that uses only CSS but requires using the same text 3 times in 3 separate divs.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
width: fit-content;
padding: 1rem;
font-size: 4rem;
overflow: hidden;
border: 1px solid black;
position: relative;
color: white; /* Hide the first text */
}
.container .bellow, .container .above {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.container .bellow span, .container .above span {
position: relative;
top: 1rem; /* Same as padding */
left: 1rem; /* Same as padding */
}
.container .bellow {
color: black; /* The text as seen normally */
}
.container .above {
color: white; /* Text color when background slides in*/
overflow: hidden;
white-space: nowrap;
background-color: red;
width: 0; /* width: 50%; --> See the effect*/
transition: width 5s;
}
.container:hover .above {
width: 100%;
}
</style>
</head>
<body>
<div class="container">
Input text (hover)
<div class="bellow">
<span>Input text (hover)</span>
</div>
<div class="above">
<span>Input text (hover)</span>
</div>
</div>
</body>
</html>
I know this is an old question, but I had the same problem and none of the solutions provided worked for my use case. I was able to achive the same effect using background-clip: text
with only an anchor tag and a ::before
pseudo-element. Note that this solution does not work on all browsers, so you may need to provide a fallback style, check the list of browsers that supports background-clip
and transform-style
properties.
The properties transform-style: preserve-3d
and translateZ(-1px)
are needed to keep the ::before
pseudo-element behind the text background.
.link {
position: relative;
cursor: pointer;
}
@supports ((background-clip: text) or (-webkit-background-clip: text)) and (transform-style: preserve-3d) {
.link {
background-size: 200% 100%;
background-position: 100%;
transition: background-position 0.25s ease;
background-clip: text;
-webkit-background-clip: text;
color: transparent;
transform-style: preserve-3d;
background-image: linear-gradient(90deg, white 50%, black 50%);
}
.link::before {
content: "";
display: block;
position: absolute;
width: 0;
height: 100%;
left: 0;
top: 0;
z-index: -1;
transform: translateZ(-1px);
transition: width 0.25s ease;
background-color: black;
}
.link:hover {
background-position: 0;
}
.link:hover::before {
width: 100%;
}
}
@supports not ((background-clip: text) or (-webkit-background-clip: text) or (transform-style: preserve-3d)) {
.link {
transition: color 0.25s ease;
}
.link:hover {
color: black;
}
}
<a class="link">Example link!</a>
I think this is more simple to understand.
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: sans-serif;
}
.titulo{
text-align: center;
margin: 2em;
}
.padre{
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
margin-top: 10em;
position: relative;
width: 1000px;
height: 500px;
}
.caja-1{
background-color: black;
width: 500px;
height: 500px;
left: 0;
mix-blend-mode: screen;
position:absolute;
}
.caja-3{
width: 500px;
height: 500px;
display: flex;
background-color: white;
position: absolute;
right: 0;
}
.texto{
font-size: 5em;
color: white;
mix-blend-mode: difference;
position:absolute;
}
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ESTILOS CONTRASTADOS CSS3</title>
</head>
<body>
<h1 class="titulo">MIX-BLEND-MODE CSS EFFECT</h1>
<div class="padre">
<div class="caja-1"></div>
<div class="caja-3"></div>
<h1 class="texto">CODE STOCK CENTER</h1>
</div>
</body>
</html>
© 2022 - 2024 — McMap. All rights reserved.