X

Headline

This is an important message requiring you to make a choice if you're based in the EU.

How to Apply CSS Styles to Only the Half of a Word or Character?

Sometimes for some reasons, maybe concerned to website design, you will need to set a character, word, or an entire sentence with half-style.

For doing it you will need to use some CSS and also JavaScript. Let’s learn how to do it below.

Half Style with the Only CSS

It is possible to have one character half-styled by using only CSS.

First, set background property with the "linear-gradient" value to your prefered direction, and specify each color with 50% visibility.

Then, set the background-clip property as background-clip: text; in order to make the background be painted within the foreground text.

The next step is to set the text-fill-color property which specifies the foreground fill color of the element's text content. Set webkit-text-fill-color: transparent; in order to let the text take the colors defined by the background property.

Example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      h1 {
      display: inline-block;
      margin: 0;
      line-height: 1em; 
      font-family: Helvetica, Arial, sans-serif;
      font-weight: bold;
      font-size: 200px;
      background: linear-gradient(to right, #1c87c9 50%, #8ebf42 50%);
      background-clip: text;
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      }
    </style>
  </head>
  <body>
    <h1>X</h1>
    <p>This is a character with half-style.</p>
  </body>
</html>

If you want to have only the half of a character and style it, just set "transparent" value for the second part of your linear gradient.

Example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      h1 {
      display: inline-block;
      margin: 0;
      line-height: 1em; 
      font-family: Helvetica, Arial, sans-serif;
      font-weight: bold;
      font-size: 200px;
      background: linear-gradient(to right, #1c87c9 50%, transparent 50%);
      background-clip: text;
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      }
    </style>
  </head>
  <body>
    <p>This character has transparent half-style. Select it to see the hidden part of it.</p>
    <h1>X</h1>
  </body>
</html>

Now, let’s discuss a case when you need to have a half-styled word, not a single character. It is not so difficult. In this case you just need to set each letter in a <span> element and apply the same style mentioned above for your span element.

Example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      span {
      display: inline-block;
      margin: 0;
      line-height: 1em; 
      font-family: Helvetica, Arial, sans-serif;
      font-weight: bold;
      font-size: 60px;
      background: linear-gradient(to right, #1c87c9 50%,#113155 50%);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      }
    </style>
  </head>
  <body>
    <div>
      <span>T</span>
      <span>E</span>
      <span>X</span>
      <span>T</span>
    </div>
  </body>
</html>

Vertical and Horizontal Half Style

Defining if the half style should be vertical or horizontal is very easy. All you need is to specify the linear gradient should be from right to left or from top to bottom.

Example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .vertical {
      display: inline-block;
      margin: 0;
      line-height: 1em; 
      font-family: Helvetica, Arial, sans-serif;
      font-weight: bold;
      font-size: 60px;
      background: linear-gradient(to right, #1c87c9 50%,#113155 50%);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      }
      .horizontal {
      display: inline-block;
      margin: 0;
      line-height: 1em; 
      font-family: Helvetica, Arial, sans-serif;
      font-weight: bold;
      font-size: 60px;
      background: linear-gradient(to top, #1c87c9 50%,#113155 50%);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      }
    </style>
  </head>
  <body>
    <div>
      <h2>I am a vertically half-styled letter.</h2>
      <span class="vertical">X</span>
      <h2>I am a horizontally half-styled letter.</h2>
      <span class="horizontal">X</span>
    </div>
  </body>
</html>

Half Style with JavaScript/jQuery

See another example where the CSS ::before pseudo element is used with JavaScript. You can set also text-shadow for your half-styled text.

Example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      body {
      font-family: Helvetica, Arial, sans-serif;   
      font-size: 60px;
      font-weight: bold;
      text-align: center;
      }
      .half-style > span {
      white-space: pre-line;
      position: relative;
      color: #1c87c9 ;
      }
      .half-style > span::before {
      content: attr(data-content);
      pointer-events: none;
      position: absolute;
      overflow: hidden;
      color: #113155;
      width: 50%;
      z-index: 1;
      }
    </style>
  </head>
  <body>
    <div class='half-style'>W3docs</div>
    <script>
      function wrapString(str) {
        var output = [];
        str.split('').forEach(function(letter) {
          var wrapper = document.createElement('span');
          wrapper.dataset.content = wrapper.innerHTML = letter;
      
          output.push(wrapper.outerHTML);
        });
      
        return output.join('');
      }
      
      window.onload = function() {
          var el  = document.querySelector('.half-style'),
              txt = el.innerHTML;
      
          el.innerHTML = wrapString(txt);
      }
    </script>
  </body>
</html>

See another example where jQuery is used to get triple effect.

Example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"
      integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
      crossorigin="anonymous"></script>
    <style>
      .halfStyle { /* base char and also the right 1/3 */
      position:relative;
      display:inline-block;
      font-size:80px; /* or any font size will work */
      color: transparent; /* hide the base character */
      overflow:hidden;
      white-space: pre; /* to preserve the spaces from collapsing */
      color: #1c87c9; /* for demo purposes */
      text-shadow: 2px 2px 0px #eee; /* for demo purposes */
      }
      .halfStyle:before { /* creates the left 1/3 */
      display:block;
      z-index:2;
      position:absolute;
      top:0;
      width: 33.33%;
      content: attr(data-content); /* dynamic content for the pseudo element */
      overflow:hidden;
      pointer-events: none; /* so the base char is selectable by mouse */
      color: #8ebf42; /* for demo purposes */
      text-shadow: 2px -2px 0px #eee; /* for demo purposes */
      }
      .halfStyle:after { /* creates the middle 1/3 */
      display:block;
      z-index:1;
      position:absolute;
      top:0;
      width: 66.66%;
      content: attr(data-content); /* dynamic content for the pseudo element */
      overflow:hidden;
      pointer-events: none; /* so the base char is selectable by mouse */
      color: #666; /* for demo purposes */
      text-shadow: 2px 2px 0px cyan; /* for demo purposes */
      }
    </style>
  </head>
  <body>
    <hr/>
    <p>Single Characters:</p>
    <span class="halfStyle" data-content="T">T</span>
    <span class="halfStyle" data-content="E">E</span>
    <span class="halfStyle" data-content="X">X</span>
    <span class="halfStyle" data-content="T">T</span>
    <hr/>
    <p>Automated on any text:</p>
    <span class="textToHalfStyle">Half-style text.</span>
    <hr/>
    <script>
      jQuery(function($) {
          var halfstyle_text, halfstyle_chars, $halfstyle_el, halfstyle_i, halfstyle_output, halfstyle_style;
      
          // Iterate over all class occurrences

          $('.textToHalfStyle').each(function(idx, halfstyle_el) {
              $halfstyle_el = $(halfstyle_el);
              halfstyle_style = $halfstyle_el.data('halfstyle') || 'hs-base';
              halfstyle_text = $halfstyle_el.text();
              halfstyle_chars = halfstyle_text.split('');
      
              // Set the screen-reader text

              $halfstyle_el.html('<span style="position: absolute;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + halfstyle_text + '</span>');
      
              // Reset output for appending

              halfstyle_output = '';
      
              // Iterate over all chars in the text

              for (halfstyle_i = 0; halfstyle_i < halfstyle_chars.length; halfstyle_i++) {
                  // Create a styled element for each character and append to container

                  halfstyle_output += '<span aria-hidden="true" class="halfStyle ' + halfstyle_style + '" data-content="' + halfstyle_chars[halfstyle_i] + '">' + halfstyle_chars[halfstyle_i] + '</span>';
              }
              // Chrome 59 and above specific fix - Part 1 - Addresses a Chrome bug where Chrome fails to corectly render and repaint pseudo elements - I came up with this fix after many different tests.

              var _applyChromeFix = !!window.chrome && !!navigator.appVersion.match(/.*Chrome\/([0-9\.]+)/) && parseInt(navigator.appVersion.match(/.*Chrome\/([0-9\.]+)/)[1], 10) >= 59;
              if (_applyChromeFix) {
                  halfstyle_output += '<style>.halfStyle{}</style>';
              }
      
              // Write to DOM only once

              $halfstyle_el.append(halfstyle_output);
      
              // Chrome 59 and above specific fix - Part 2

              if (_applyChromeFix) {
                  setTimeout(function(){
                      $halfstyle_el.find('style').remove();
                  }, 0);
              }
          });
      });
    </script>
  </body>
</html>

Do you find this helpful?

Related articles