Is it possible to apply CSS to half of a character?

Content from DOC https://q.houxu6.top/?s=Is it possible to apply CSS to half of a character?

What I’m looking for:

A way to style half of a character. (In this case half of the letters are transparent)

What I have searched for and tried so far (without success):

  • Method used to style characters/letters
  • Styling part of a character using CSS or JavaScript
  • Apply CSS to 50% of characters

Below is an example of what I want to achieve.

!x

Is there a CSS or JavaScript solution, or do I need to rely on images? I don’t want to go with an image scheme because this text will end up dynamically generated.

Update:

Since a lot of people asked me why I styled half of the characters, this is why. My city recently spent $250,000 to define a new “brand” for itself. This is the logo I found. Many people expressed dissatisfaction with this simple and uncreative design and continue to complain. My goal was to make this website as a joke. Type ‘Halifax’ and you’ll see what I mean.

Now on GitHub as a plugin!

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly Please feel free to fork and improve.

Demo | Download ZIP | Half-Style.com (redirects to GitHub)

  • Pure CSS for single characters
  • JavaScript for automation across text or multiple characters
  • Preserve text accessibility for screen readers for use by people who are blind or visually impaired

Part 1: Basic Solution

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly

Demo: http://jsfiddle.net/arbel/pd9yB/1694/

This method works with any dynamic text or single characters, and it’s all automated. All you need to do is add a class on the target text and it does the rest.

Additionally, the accessibility of the original text is preserved for screen readers who are blind or visually impaired.

Explanation of individual characters:

Pure CSS. All you need to do is apply the .halfStyle class to every element that contains the characters you want to half-style.

For each span element that contains characters, you can create a data attribute, like here data-content="X", and use content: attr(data -content);, this way the .halfStyle:before class will be dynamic and you don’t need to hardcode it for each instance.

Interpretation of any text:

Just add the textToHalfStyle class to the element containing the text.

// jQuery is used in automation mode
jQuery(function($) {
    var text, chars, $el, i, output;

    // Traverse the occurrences of all classes
    $('.textToHalfStyle').each(function(idx, el) {
    $el = $(el);
    text = $el.text();
    chars = text.split('');

    // Set screen reader text
    $el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + text + '</span>');

    //Reset output to append
    output = '';

    //Loop through all characters in the text
    for (i = 0; i < chars.length; i + + ) {
        //Create a styled element for each character and attach it to the container
        output + = '<span aria-hidden="true" class="halfStyle" data-content="' + chars[i] + '">' + chars[i] + '</span>';
    }

    //Write to DOM only once
    $el.append(output);
  });
});
.halfStyle {
    position: relative;
    display: inline-block;
    font-size: 80px; /* or any font size will work */
    color: black; /* or transparent, any color is acceptable */
    overflow: hidden;
    white-space: pre; /* Keep spaces from being folded */
}

.halfStyle:before {
    display: block;
    z-index: 1;
    position: absolute;
    top: 0;
    left: 0;
    width: 50%;
    content: attr(data-content); /* Dynamic content of pseudo-element */
    overflow: hidden;
    color: #f00;
}
<script src="//i2.wp.com/ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p>Single character:</p>
<span class="halfStyle" data-content="X">X</span>
<span class="halfStyle" data-content="Y">Y</span>
<span class="halfStyle" data-content="Z">Z</span>
<span class="halfStyle" data-content="A">A</span>

<hr/>
<p>automation:</p>

<span class="textToHalfStyle">Half style, please. </span>

(JSFiddle demo)

Part 2: Advanced Solution – Separate Left and Right Half

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly
Using this solution you can style the left and right sections separately.

All things being equal, only more advanced CSS can achieve this magic.

Show code snippet

jQuery(function($) {<!-- -->
    var text, chars, $el, i, output;

    // Traverse the occurrences of all classes
    $('.textToHalfStyle').each(function(idx, el) {<!-- -->
        $el = $(el);
        text = $el.text();
        chars = text.split('');

        // Set screen reader text
        $el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + text + '</span>');

        //Reset output to append
        output = '';

        //Loop through all characters in the text
        for (i = 0; i < chars.length; i + + ) {<!-- -->
            //Create a styled element for each character and attach it to the container
            output + = '<span aria-hidden="true" class="halfStyle" data-content="' + chars[i] + '">' + chars[i] + '</span>';
        }

        //Write to DOM only once
        $el.append(output);
    });
});
.halfStyle {<!-- -->
    position: relative;
    display: inline-block;
    font-size: 80px; /* or any font size will work */
    color: transparent; /* Hide basic characters */
    overflow: hidden;
    white-space: pre; /* Keep spaces from being folded */
}

.halfStyle:before {<!-- --> /* Create the left part */
    display: block;
    z-index: 1;
    position: absolute;
    top: 0;
    width: 50%;
    content: attr(data-content); /* Pseudo element dynamic content */
    overflow: hidden;
    pointer-events: none; /* so that basic characters can be selected by mouse */
    color: #f00; /* Demonstration purpose */
}

.halfStyle:after {<!-- --> /* Create the right part */
    display: block;
    direction: rtl; /* Very important, width will start from the right */
    position: absolute;
    z-index: 2;
    top: 0;
    left: 50%;
    width: 50%;
    content: attr(data-content); /* Pseudo element dynamic content */
    overflow: hidden;
    pointer-events: none; /* so that basic characters can be selected by mouse */
    color: #000; /* Demonstration purpose */
}
<script src="//i2.wp.com/ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>Single character:</p>
<span class="halfStyle" data-content="X">X</span>
<span class="halfStyle" data-content="Y">Y</span>
<span class="halfStyle" data-content="Z">Z</span>
<span class="halfStyle" data-content="A">A</span>

<hr/>
<p>automatic:</p>

<span class="textToHalfStyle">Half style, please. </span>

(JSFiddle demo)

Part 3: Mixing Matches and Improvements

Now that we know the possibilities, let’s create some variations.

-Horizontal half

  • Without text shadow:

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly

  • Text shadow can be set independently for each half:

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly

//jQuery for automation mode
jQuery(function($) {
    var text, chars, $el, i, output;

    // Traverse all classes to appear
    $('.textToHalfStyle').each(function(idx, el) {
        $el = $(el);
        text = $el.text();
        chars = text.split('');

        // Set screen reader text
        $el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + text + '</span>');

        //Reset output to append
        output = '';

        //Loop through all characters in the text
        for (i = 0; i < chars.length; i + + ) {
            //Create a style element for each character and attach it to the container
            output + = '<span aria-hidden="true" class="halfStyle" data-content="' + chars[i] + '">' + chars[i] + '</span>';
        }

        //Write to DOM only once
        $el.append(output);
    });
});
.halfStyle {
  position: relative;
  display: inline-block;
  font-size: 80px; /* or any font size will work */
  color: transparent; /* Hide basic characters */
  overflow: hidden;
  white-space: pre; /* Keep spaces from being folded */
}

.halfStyle:before { /* Create the top part */
  display: block;
  z-index: 2;
  position: absolute;
  top: 0;
  height: 50%;
  content: attr(data-content); /* Pseudo element dynamic content */
  overflow: hidden;
  pointer-events: none; /* Make basic characters selectable with the mouse */
  color: #f00; /* Demonstration purpose */
}

.halfStyle:after { /* Create bottom part */
  display: block;
  position: absolute;
  z-index: 1;
  top: 0;
  height: 100%;
  content: attr(data-content); /* Pseudo element dynamic content */
  overflow: hidden;
  pointer-events: none; /* Make basic characters selectable with the mouse */
  color: #000; /* Demonstration purpose */
}
<script src="//i2.wp.com/ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>Single character:</p>
<span class="halfStyle" data-content="X">X</span>
<span class="halfStyle" data-content="Y">Y</span>
<span class="halfStyle" data-content="Z">Z</span>
<span class="halfStyle" data-content="A">A</span>

<hr/>
<p>automation:</p>

<span class="textToHalfStyle">Half style, please. </span>

(JSFiddle demo)

.halfStyle { /\* Basic characters and right 1/3 \*/
    position: relative;
    display: inline-block;
    font-size: 80px; /\* or any font size will work \*/
    color: transparent; /\* Hide basic characters \*/
    overflow: hidden;
    white-space: pre; /\* Keep spaces from being folded \*/
    color: #f0f; /\* Demonstration purpose \*/
    text-shadow: 2px 2px 0px #0af; /\* Demonstration use \*/
}

.halfStyle:before { /\* Create left 1/3 \*/
    display: block;
    z-index: 2;
    position: absolute;
    top: 0;
    width: 33.33%;
    content: attr(data-content); /\* Dynamic content of pseudo-element \*/
    overflow: hidden;
    pointer-events: none; /\* Make basic characters mouse selectable \*/
    color: #f00; /\* Demonstration purpose \*/
    text-shadow: 2px -2px 0px #af0; /\* Demonstration purpose \*/
}

.halfStyle:after { /\* Create middle 1/3 \*/
    display: block;
    z-index: 1;
    position: absolute;
    top: 0;
    width: 66.66%;
    content: attr(data-content); /\* Dynamic content of pseudo-element \*/
    overflow: hidden;
    pointer-events: none; /\* Make basic characters mouse selectable \*/
    color: #000; /\* Demonstration purpose \*/
    text-shadow: 2px 2px 0px #af0; /\* Demonstration purpose \*/
}
<script src="//i2.wp.com/ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p>Single character:</p>
<span class="halfStyle" data-content="X">X</span>
<span class="halfStyle" data-content="Y">Y</span>
<span class="halfStyle" data-content="Z">Z</span>
<span class="halfStyle" data-content="A">A</span>

<hr/>
<p>automation:</p>

<span class="textToHalfStyle">Please show the half style. </span>

(JSFiddle demo)
Half-shaped style improvements by @SamTremaine

!halfStyle – Sam Tremaine

Show code snippet

// jQuery for automated mode
jQuery(function($) {<!-- -->
    var text, chars, $el, i, output;

    // Iterate over all class occurrences
    $('.textToHalfStyle').each(function(idx, el) {<!-- -->
    $el = $(el);
    text = $el.text();
    chars = text.split('');

    // Set the screen-reader text
    $el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + text + '</span>');

    //Reset output for appending
    output = '';

    // Iterate over all chars in the text
    for (i = 0; i < chars.length; i + + ) {<!-- -->
        // Create a styled element for each character and append to container
        output + = '<span aria-hidden="true" class="peelingStyle" data-content="' + chars[i] + '">' + chars[i] + '</span>';
    }

    // Write to DOM only once
    $el.append(output);
  });
});
body {<!-- -->
    background-color: black;
}

.textToHalfStyle {<!-- -->
    display: block;
    margin: 200px 0 0 0;
    text-align: center;
}

.peelingStyle {<!-- -->
    font-family: 'Libre Baskerville', serif;
    position: relative;
    display: inline-block;
    width: 1;
    font-size: 70px;
    color: black;
    overflow: hidden;
    white-space: pre;
    text-shadow: 1px 2px 0 white;
}

.peelingStyle:before {<!-- -->
    display: block;
    z-index: 1;
    position: absolute;
    top: 0;
    width: 50%;
    content: attr(data-content); /\* dynamic content for the pseudo element \*/
    overflow: hidden;
    color: white;
}
<script src="//i2.wp.com/ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>Single Characters:</p>
<span class="halfStyle" data-content="X">X</span>
<span class="halfStyle" data-content="Y">Y</span>
<span class="halfStyle" data-content="Z">Z</span>
<span class="halfStyle" data-content="A">A</span>

<hr/>
<p>Automated:</p>

<span class="textToHalfStyle">Half-style, please.</span>

(JSFiddle demo)

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly

Show code snippet

// jQuery for automated mode
jQuery(function($) {<!-- -->
    var text, chars, $el, i, output;

    // Traverse the occurrences of all classes
    $('.textToHalfStyle').each(function(idx, el) {<!-- -->
        $el = $(el);
        text = $el.text();
        chars = text.split('');

        // Set screen reader text
        $el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + text + '</span>');

        //Reset output to append
        output = '';

        //Loop through all characters in the text
        for (i = 0; i < chars.length; i + + ) {<!-- -->
            // Create a style element for each character and attach it to the container
            output + = '<span aria-hidden="true" class="halfStyle" data-content="' + chars[i] + '">' + chars[i] + '</span>';
        }

        //Write to DOM only once
        $el.append(output);
    });
});
.halfStyle {<!-- -->
    position: relative;
    display: inline-block;
    font-size: 68px;
    color: rgba(0, 0, 0, 0.8);
    overflow: hidden;
    white-space: pre;
    transform: rotate(4deg);
    text-shadow: 2px 1px 3px rgba(0, 0, 0, 0.3);
}

.halfStyle:before {<!-- --> /* Create the left part */
    display: block;
    z-index: 1;
    position: absolute;
    top: -0.5px;
    left: -3px;
    width: 100%;
    content: attr(data-content);
    overflow: hidden;
    pointer-events: none;
    color: #FFF;
    transform: rotate(-4deg);
    text-shadow: 0px 0px 1px #000;
}
<script src="//i2.wp.com/ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>Single character:</p>
<span class="halfStyle" data-content="X">X</span>
<span class="halfStyle" data-content="Y">Y</span>
<span class="halfStyle" data-content="Z">Z</span>
<span class="halfStyle" data-content="A">A</span>

<hr/>
<p>automation:</p>

<span class="textToHalfStyle">Half style, please. </span>

(JSFiddle demo) and samtremaine.co.uk

Part 4: Preparing for Production

Different sets of Half-Style styles can be used on the same page. You can define multiple style sets and tell the plugin which one to use.

The plugin uses the data attribute data-halfstyle="[-CustomClassName-]" on the target .textToHalfStyle element and automatically makes all necessary changes.

So just add the textToHalfStyle class and use the data attribute data-halfstyle="[-CustomClassName-]" on the element containing the text. The plugin will do the rest.

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly

Additionally, the class definition of the CSS style set matches the [-CustomClassName-] part mentioned above and is linked to .halfStyle, so we will have .halfStyle .[-CustomClassName-]

jQuery(function($) {
    var halfstyle_text, halfstyle_chars, $halfstyle_el, halfstyle_i, halfstyle_output, halfstyle_style;

    // Traverse the occurrences of all classes
    $('.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 screen reader text
        $halfstyle_el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + halfstyle_text + '</span>');

        //Reset output to append
        halfstyle_output = '';

        //Loop through all characters in the text
        for (halfstyle_i = 0; halfstyle_i < halfstyle_chars.length; halfstyle_i + + ) {
            //Create a style element for each character and attach it to the container
            halfstyle_output + = '<span aria-hidden="true" class="halfStyle ' + halfstyle_style + '" data-content="' + halfstyle_chars[halfstyle_i] + '">\ ' + halfstyle_chars[halfstyle_i] + '</span>';
        }

        //Write to DOM only once
        $halfstyle_el.append(halfstyle_output);
    });
});
/* Start half style hs-base */

.halfStyle.hs-base {
    position: relative;
    display: inline-block;
    font-size: 80px; /* or any font size will work */
    overflow: hidden;
    white-space: pre; /* Keep spaces from being folded */
    color: #000; /* Demonstration purpose */
}

.halfStyle.hs-base:before {
    display: block;
    z-index: 1;
    position: absolute;
    top: 0;
    width: 50%;
    content: attr(data-content); /* Pseudo element dynamic content */
    pointer-events: none; /* so that the mouse can select basic characters */
    overflow: hidden;
    color: #f00; /* Demonstration purpose */
}

/* End half style hs-base */

/* Start half style hs-horizontal-third */

.halfStyle.hs-horizontal-third { /* Basic characters and bottom 1/3 */
    position: relative;
    display: inline-block;
    font-size: 80px; /* or any font size will work */
    color: transparent;
    overflow: hidden;
    white-space: pre; /* Keep spaces from being folded */
    color: #f0f;
    text-shadow: 2px 2px 0px #0af; /* Demonstration purpose */
}

.halfStyle.hs-horizontal-third:before { /* Create the top 1/3 */
    display: block;
    z-index: 2;
    position: absolute;
    top: 0;
    height: 33.33%;
    content: attr(data-content); /* Pseudo element dynamic content */
    overflow: hidden;
    pointer-events: none; /* so that the mouse can select basic characters */
    color: #f00; /* Demonstration purpose */
    text-shadow: 2px -2px 0px #fa0; /* Demonstration purpose */
}

.halfStyle.hs-horizontal-third:after { /* Create the middle 1/3 */
    display: block;
    position: absolute;
    z-index: 1;
    top: 0;
    height: 66.66%;
    content: attr(data-content); /* Pseudo element dynamic content */
    overflow: hidden;
    pointer-events: none; /* so that the mouse can select basic characters */
    color: #000; /* Demonstration purpose */
    text-shadow: 2px 2px 0px #af0; /* Demonstration purpose */
}

/* End half style hs-horizontal-third */

/* Start half style hs-PeelingStyle, contributed by user SamTremaine on Stackoverflow.com */

.halfStyle.hs-PeelingStyle {
  position: relative;
  display: inline-block;
  font-size: 68px;
  color: rgba(0, 0, 0, 0.8);
  overflow: hidden;
  white-space: pre;
  transform: rotate(4deg);
  text-shadow: 2px 1px 3px rgba(0, 0, 0, 0.3);
}

.halfStyle.hs-PeelingStyle:before { /* Create the left part */
  display: block;
  z-index: 1;
  position: absolute;
  top: -0.5px;
  left: -3px;
  width: 100%;
  content: attr(data-content);
  overflow: hidden;
  pointer-events: none;
  color: #FFF;
  transform: rotate(-4deg);
  text-shadow: 0px 0px 1px #000;
}

/* End half style hs-PeelingStyle */

/* Start half-style hs-KevinGranger, contributed by user KevinGranger on StackOverflow.com */

.textToHalfStyle.hs-KevinGranger {
  display: block;
  margin: 200px 0 0 0;
  text-align: center;
}

.halfStyle.hs-KevinGranger {
  font-family: 'Libre Baskerville', serif;
  position: relative;
  display: inline-block;
  width: 1;
  font-size: 70px;
  color: black;
  overflow: hidden;
  white-space: pre;
  text-shadow: 1px 2px 0 white;
}

.halfStyle.hs-KevinGranger:before {
  display: block;
  z-index: 1;
  position: absolute;
  top: 0;
  width: 50%;
  content: attr(data-content); /* Pseudo element dynamic content */
  overflow: hidden;
  color: white;
}

/* End half style hs-KevinGranger */
<script src="//i2.wp.com/ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-base">Half style is a dream come true. </span>
</p>
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-horizontal-third">Half style is a dream come true. </span>
</p>
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-PeelingStyle">Half style is what you want. </span>
</p>
<p style="background-color:#000;">
    <span class="textToHalfStyle" data-halfstyle="hs-KevinGranger">Half style is what you want. </span>
</p>

(JSFiddle demo)