Splitting Text Color with CSS when compared to the background
Asked Answered
C

4

13

I'm trying to achieve the following but really struggling. I simply am trying to achieve a diagonal background which goes through the text and changes the colour my choice.

Split Text Image Example

I'ved tried using css mixed-blend-mode however it just contrasts my colors rather than having the option to split into two different colors.

* {
  margin: 0;
  padding: 0
}

header {
  overflow: hidden;
  height: 100vh;
  background-color: #FFF;
  background-image: -webkit-linear-gradient(30deg, #FFF 50%, #adf175 50%);
  min-height: 500px;
}

h2 {
  color: white;
  font: 900 35vmin/35vh cookie, cursive;
  text-align: center;
  position: fixed;
  top: 0px;
  left: 20px;
  mix-blend-mode: difference;
}

h2:after {
  color: white;
  mix-blend-mode: difference;
}
<header>
  <h2>On A Mission</h2>
</header>
Canzona answered 9/11, 2018 at 9:29 Comment(1)
Agreed with answerers, you definitively should take a look at SVG!Hoo
G
7

Clipping is an excellent solution.

But if you have the freedom of applying the gradient on the text of h2 , then it can be done with a little switcheroo trick.

h2 {
  background: linear-gradient(30deg, #adf175 50%, #FFF 50%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

Basically, one applies the linear-gradient background on the text element , h2 in this case, and use background-clip property to clip the background to extend to the text only . Finally use the text-fill-color to set the color of the h2 to transparent

I had just reversed the gradient colors from the question above for the h2 and the div .

More info can be seen here

body {
  font-size: 16px;
  font-family: Verdana, sans-serif;
}

.wrap {
  width: 50%;
  margin: 0 auto;
  border: 1px solid #ccc;
  text-align: center;
  background: linear-gradient(30deg, #FFF 50%, #adf175 50%);
}

h2 {
  background: linear-gradient(30deg, #adf175 50%, #FFF 50%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
<div class="wrap">
  <h2>Hello World</h2>
</div>

Caution : background-clip:text is an experimental tech

Gazehound answered 9/11, 2018 at 10:4 Comment(0)
F
5

* {
  margin: 0;
  padding: 0
}

header {
  position: relative;
  height: 100vh;
  min-height: 500px;
  font: 900 35vmin/35vh cookie, cursive;
  text-align: center;
  color: #adf175;
}

header > div {
  min-height: 100%;
}

.foreground {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: #adf175;
  color: white;
  clip-path: polygon(30% 0, 100% 100%, 100% 0);
}

h2 {
  position: fixed;
}
<header>
    <div>
        <h2>On A Mission</h2>
    </div>
    <div class="foreground">
        <h2>On A Mission</h2>
    </div>
</header>

Blend modes are fixed formulas which you can use creatively. They mix two overlapping images (visual appearances) together. So the parameters are the two overlaying pixels nothing else.

But you can create such an effect with a little help of #clippath, #svg, #javascript or the like. See this website for example: https://mathieulevesque.com/en I guess they doubled the text and gave it two different appearances.

I just created a quick prototype. you can play with. Hope it helps.

If you want to go with clean code, you can create the second div with the help of javascript.

This tool could help you playing around with shapes.

Forebode answered 9/11, 2018 at 9:45 Comment(0)
G
2

Here is another idea using more supported features than clip-path and background-clip:text. The idea is to rely on skew transformation and some hidden overflow.

I used CSS variables for better flexibility but they can easily be omitted in case we need old browser support.

:root {
  --c1:#adf175;
  --c2:#f3f3f3;
}

.box {
  font-size: 20px;
  font-family: Verdana, sans-serif;
  color:var(--c1);
  background:var(--c2);
  padding:20px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.box:before {
  content:var(--text);
}
.box span {
  position:absolute;
  top:0;
  left:-20px;
  right:var(--p,50%);
  bottom:0;
  padding:inherit;
  background:var(--c1);
  color:var(--c2);
  white-space:nowrap;
  overflow:hidden;
  transform:skew(15deg);
}
.box span:before{
  content:var(--text);
  display:inline-block;
  margin-left:20px; /*Same value as left on the span*/
  transform:skew(-15deg); /*same value as the skew on the span*/
}
<div class="box" style="--text:'Lorem Ipsum'">
<span></span>
</div>
<div class="box" style="--text:'Lorem Ipsum';--p:20%">
<span></span>
</div>
<div class="box" style="--text:'Lorem Ipsum';--p:80%">
<span></span>
</div>

We can introduce another variable to control the skewing:

:root {
  --c1:#adf175;
  --c2:#f3f3f3;
}
.box {
  font-size: 20px;
  font-family: Verdana, sans-serif;
  color:var(--c1);
  background-color:var(--c2);
  padding:20px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.box:before {
  content:var(--text);
}
.box span {
  position:absolute;
  top:0;
  left:-50px;
  right:var(--p,50%);
  bottom:0;
  padding:inherit;
  color:var(--c2);
  background-color:var(--c1);
  white-space:nowrap;
  overflow:hidden;
  transform:skew(var(--s,15deg));
}
.box span:before{
  content:var(--text);
  display:inline-block;
  margin-left:50px; /*Same value as left on the span*/
  transform:skew(calc(-1 * var(--s,15deg)));
}
<div class="box" style="--text:'Lorem Ipsum'">
<span></span>
</div>
<div class="box" style="--text:'Lorem Ipsum';--p:20%;--s:-30deg">
<span></span>
</div>
<div class="box" style="--text:'Lorem Ipsum';--p:70%;--s:45deg">
<span></span>
</div>

We can also consider multiline text:

:root {
  --c1:#adf175;
  --c2:#f3f3f3;
}
.box {
  font-size: 20px;
  font-family: Verdana, sans-serif;
  color:var(--c1);
  background-color:var(--c2);
  padding:20px;
  position:relative;
  display:inline-block;
  overflow:hidden;
  --w:140px;
  width:var(--w); /*we fix the width to have multiple lines*/
}
.box:before {
  content:var(--text);
}
.box span {
  position:absolute;
  top:0;
  left:-50px;
  right:var(--p,50%);
  bottom:0;
  padding:inherit;
  color:var(--c2);
  background-color:var(--c1);
  overflow:hidden;
  transform:skew(var(--s,15deg));
}
.box span:before{
  content:var(--text);
  width:var(--w); /* we use the same width as the box*/
  display:inline-block;
  margin-left:50px; /*Same value as left on the span*/
  transform:skew(calc(-1 * var(--s,15deg)));
}
<div class="box" style="--text:'Lorem Ipsum dolert text'">
<span></span>
</div>
<div class="box" style="--text:'Lorem Ipsum dolert text';--p:20%;--s:-30deg">
<span></span>
</div>
<div class="box" style="--text:'Lorem Ipsum dolert text';--p:40%;--s:45deg">
<span></span>
</div>
Georgetown answered 9/11, 2018 at 20:11 Comment(0)
S
1

So this can be done using background-clip: text - although this is not universally supported, it does work in the latest Chrome, Firefox and Edge:

.container {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

.rotate {
  border: 1px solid #ddd;
  text-align: center;
  background: linear-gradient(75deg, #adf175 50%, transparent 50%);
  transform: rotate(-90deg);
}

.text {
  font-family: arial, sans-serif;
  font-size: 1.5em;
  font-weight: bold;
  padding: 5px;
  margin: 0;
  text-transform: uppercase;
  background: linear-gradient(75deg, #fff 50%, #adf175 50%);
  color: transparent;
  -webkit-background-clip: text;
  -moz-background-clip: text;
  background-clip: text;
}

.fit-text {
  font-size: 2.25rem;
}
<div class="container">

  <div class="rotate">
    <div class="text">we are on a
      <div class="fit-text">mission</div>
    </div>
  </div>

  <div class="rotate">
    <div class="text">we are on a<br/>mission</div>
  </div>
</div>

This solution includes rotating the result and expanding the last word to fit (the way your example image looks) - I have included a non-expanded version as well.

Selenite answered 9/11, 2018 at 13:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.