- This topic is empty.
-
AuthorPosts
-
January 14, 2016 at 9:41 am #9121David HoangKeymaster
This can be achieved with just CSS
:before
selector andcontent property value
..halfed, .halfed1 { float: left; } .halfed, .halfed1 { font-family: arial; font-size: 300px; font-weight: bolder; width: 200px; height: 300px; position: relative; /* To help hold the content value within */ overflow: hidden; color: #000; } .halfed:before, .halfed1:before { width: 50%; /* How much we'd like to show */ overflow: hidden; /* Hide what goes beyond our dimension */ content: 'X'; /* Halfed character */ height: 100%; position: absolute; color: #28507D; } /* For Horizontal cut off */ .halfed1:before { width: 100%; height: 55%; }
<div class="halfed"> X </div> <div class="halfed1"> X </div>
May 4, 2017 at 12:44 pm #9119David HoangKeymasterYou can use below code. Here in this example I have used
h1
tag and added an attributedata-title-text="Display Text"
which will appear with different color text onh1
tag text element, which gives effect halfcolored text as shown in below examplebody { text-align: center; margin: 0; } h1 { color: #111; font-family: arial; position: relative; font-family: 'Oswald', sans-serif; display: inline-block; font-size: 2.5em; } h1::after { content: attr(data-title-text); color: #e5554e; position: absolute; left: 0; top: 0; clip: rect(0, 1000px, 30px, 0); }
<h1 data-title-text="Display Text">Display Text</h1>
June 19, 2017 at 7:58 am #9123David HoangKeymasterHow about something like this for shorter text?
It could even work for longer text if you did something with a loop, repeating the characters with JavaScript. Anyway, the result is something like this:
p.char { position: relative; display: inline-block; font-size: 60px; color: red; } p.char:before { position: absolute; content: attr(char); width: 50%; overflow: hidden; color: black; }
<p class="char" char="S">S</p> <p class="char" char="t">t</p> <p class="char" char="a">a</p> <p class="char" char="c">c</p> <p class="char" char="k">k</p> <p class="char" char="o">o</p> <p class="char" char="v">v</p> <p class="char" char="e">e</p> <p class="char" char="r">r</p> <p class="char" char="f">f</p> <p class="char" char="l">l</p> <p class="char" char="o">o</p> <p class="char" char="w">w</p>
December 15, 2018 at 10:26 am #9118David HoangKeymasterJust for the record in history!
I’ve come up with a solution for my own work from 5-6 years ago, which is Gradext ( pure javascript and pure css, no dependency ) .
The technical explanation is you can create an element like this:
<span>A</span>
now if you want to make a gradient on text, you need to create some multiple layers, each individually specifically colored and the spectrum created will illustrate the gradient effect.
for example look at this is the word lorem inside of a
<span>
and will cause a horizontal gradient effect ( check the examples ):<span data-i="0" style="color: rgb(153, 51, 34);">L</span> <span data-i="1" style="color: rgb(154, 52, 35);">o</span> <span data-i="2" style="color: rgb(155, 53, 36);">r</span> <span data-i="3" style="color: rgb(156, 55, 38);">e</span> <span data-i="4" style="color: rgb(157, 56, 39);">m</span>
and you can continue doing this pattern for a long time and long paragraph as well.
But!
What if you want to create a vertical gradient effect on texts?
Then there’s another solution which could be helpful. I will describe in details.
Assuming our first
<span>
again. but the content shouldn’t be the letters individually; the content should be the whole text, and now we’re going to copy the same â€â€<span>
again and again ( count of spans will define the quality of your gradient, more span, better result, but poor performance ). have a look at this:<span data-i="6" style="color: rgb(81, 165, 39); overflow: hidden; height: 11.2px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span> <span data-i="7" style="color: rgb(89, 174, 48); overflow: hidden; height: 12.8px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span> <span data-i="8" style="color: rgb(97, 183, 58); overflow: hidden; height: 14.4px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span> <span data-i="9" style="color: rgb(105, 192, 68); overflow: hidden; height: 16px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span> <span data-i="10" style="color: rgb(113, 201, 78); overflow: hidden; height: 17.6px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span> <span data-i="11" style="color: rgb(121, 210, 88); overflow: hidden; height: 19.2px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span>
Again, But!
what if you want to make these gradient effects to move and create an animation out of it?
well, there’s another solution for it too. You should definitely check
animation: true
or even.hoverable()
method which will lead to a gradient to start based on cursor position! ( sounds cool xD )this is simply how we’re creating gradients ( linear or radial ) on texts. If you liked the idea or want to know more about it, you should check the links provided.
Maybe this is not the best option, maybe not the best performant way to do this, but it will open up some space to create exciting and delightful animations to inspire some other people for a better solution.
It will allow you to use gradient style on texts, which is supported by even IE8!
Here you can find a working live demo and the original repository is here on GitHub as well, open source and ready to get some updates ( 😀 )
This is my first time ( yeah, after 5 years, you’ve heard it right ) to mention this repository anywhere on the Internet, and I’m excited about that!
[Update – 2019 August:] Github removed github-pages demo of that repository because I’m from Iran! Only the source code is available here tho…
February 20, 2021 at 11:38 am #9116David HoangKeymasterHere is a CSS only solution for a full line of text, not just a character element.
div { position: relative; top: 2em; height: 2em; text-transform: full-width; } div:before, div:after { content: attr(data-content); position: absolute; top: 0; right: 0; bottom: 0; left: 0; } div:after { color: red; /* mask for a single character. By repeating this mask, all the string becomes masked */ -webkit-mask-image: linear-gradient(to right, transparent 0, transparent .5em, white .5em, white 1em); -webkit-mask-repeat: repeat-x; /* repeat the mask towards the right */ -webkit-mask-size: 1em; /* relative width of a single character */ /* non-vendor mask settings */ mask-image: linear-gradient(to right, transparent 0, transparent .5em, white .5em, white 1em); mask-repeat: repeat-x; mask-size: 1em; } /* demo purposes */ input[name="fontSize"]:first-of-type:checked ~ div { font-size: 1em; } input[name="fontSize"]:first-of-type + input:checked ~ div { font-size: 2em; } input[name="fontSize"]:first-of-type + input + input:checked ~ div { font-size: 3em; }
Font-size: <input type="radio" name="fontSize" value="1em"> <input type="radio" name="fontSize" value="2em" checked> <input type="radio" name="fontSize" value="3em"> <div data-content="A CSS only solution..."></div> <div data-content="Try it on Firefox!"></div>
The idea is to apply an horizontal CSS mask for each character, that hides the first half of it [0 – 0.5em] and shows the second half [0.5em – 1em].
The width of the mask is
mask-size: 1em
to match the width of the very first character in the string.
By using themask-repeat: repeat-x
, the same mask is applied to the second, third character and so on.I thought that using the font
monospace
would solve the problem of using same-width letters, but I was wrong.
Instead, I solved it by using thetext-transform: full-width
, that unfortunatelly is only supported by Firefox, I believe.The use of relative unit
em
allows the design to scale up/down depending on thefont-size
.Vanilla JavaScript solution for all browsers
If Firefox is not an option, then use this script for the rescue.
It works by inserting a child
span
for each character. Inside each span, a non-repeated CSS mask is placed from [0% – 50%] and [50% – 100%] the width of the letter (which is the width of the span element).This way we don’t have anymore the restriction of using same-width characters.
const dataElement = document.getElementById("data"), content = dataElement.textContent, zoom = function (fontSize) { dataElement.style['font-size'] = fontSize + 'em'; }; while (dataElement.firstChild) { dataElement.firstChild.remove() } for(var i = 0; i < content.length; ++i) { const spanElem = document.createElement('span'), ch = content[i]; spanElem.setAttribute('data-ch', ch); spanElem.appendChild(document.createTextNode(ch === ' ' ? '\u00A0' : ch)); data.appendChild(spanElem); }
#data { position: relative; top: 2em; height: 2em; font-size: 2em; } #data span { display: inline-block; position: relative; color: transparent; } #data span:before, #data span:after { content: attr(data-ch); display: inline-block; position: absolute; top: 0; right: 0; bottom: 0; left: 0; text-align: center; color: initial; } #data span:after { color: red; -webkit-mask-image: linear-gradient(to right, transparent 0, transparent 50%, white 50%, white 100%); mask-image: linear-gradient(to right, transparent 0, transparent 50%, white 50%, white 100%); }
Font-size: <input type="range" min=1 max=4 step=0.05 value=2 oninput="zoom(this.value)" onchange="zoom(this.value)"> <div id="data">A Fallback Solution...For all browsers</div>
January 19, 2022 at 4:35 am #9117David HoangKeymasterAll solutions work by splitting letters and wrapping them in
<span>
. We don’t have to split letters in two cases:- If font is monospace.
- If vertical layout is used.
div { font-size: 80px; font-weight: bolder; color: transparent; padding: 0; margin: 0; background: linear-gradient(90deg, rgb(34, 67, 143) 0% 50%, #409FBF 50%); background-clip: text; -webkit-background-clip: text; } .one { font-family: 'Nova Mono'; background-repeat: repeat-x; background-size: 45px; } .two { font-family: 'Gideon Roman'; writing-mode: vertical-lr; text-orientation: upright; letter-spacing: -35px; height: 500px; }
<!-- get the fonts --> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Nova+Mono&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Gideon+Roman&display=swap" rel="stylesheet"> <div id='one' class="one">X-RAY Winter</div> <div class="two">Minty</div>
Expected output, in case the fonts are not available:
I know use of background-clip and gradient has been already demonstrated in other answers, just putting the cases where you don’t have to split the letters.
-
AuthorPosts
- You must be logged in to reply to this topic.