Question
I want to style only one half of a single character—for example, making half of a letter transparent.
I have looked for approaches such as:
- Styling half of a character or letter
- Styling part of a character with CSS or JavaScript
- Applying CSS to 50% of a character
I am trying to achieve an effect where one side of a letter looks different from the other.
Is there a CSS or JavaScript solution for this, or would I need to use images? I would prefer to avoid images because the text is generated dynamically.
Short Answer
By the end of this page, you will understand why CSS cannot directly target “half of a character” as a true text sub-unit, and how developers usually create this effect with layering, clipping, gradients, or duplicated text. You will also see practical examples for dynamic text and learn which approach works best in real projects.
Concept
In CSS, a character is normally rendered as a single glyph by the browser's text engine. That means CSS can style the whole text node, the whole element, or sometimes pseudo-elements like ::before and ::after, but it cannot directly select the left half of a single glyph as if it were a separate DOM element.
So the key idea is this:
- You usually cannot style half a character directly.
- You can create the visual effect of half-styled text using other CSS techniques.
Common solutions include:
- Duplicating the text and placing one copy on top of the other
- Clipping one layer so only half remains visible
- Using a gradient as the text fill
- Using SVG when you need more precise control
Why this matters in real programming:
- Decorative headings often need split-color text.
- Logos and branding sometimes require partial text fills.
- Interactive UI effects may reveal part of a word during animation.
- Dynamically generated text needs CSS-based techniques rather than static images.
If the content changes at runtime, CSS and JavaScript solutions are usually better than images because they remain scalable, editable, and accessible.
Mental Model
Think of a letter like a sticker printed on clear plastic.
You cannot easily grab just the left half of the ink as a separate object.
But you can do this:
- print the same sticker twice,
- put one copy on top of the other,
- cover part of the top sticker,
- and let the bottom sticker show through.
That is how most “half-character styling” effects work on the web. You are not editing half the letter itself. You are layering and hiding parts so it looks like half the character has a different style.
Syntax and Examples
A common CSS approach is to duplicate the text using a pseudo-element and clip one copy.
<h1 class="split" data-text="A">A</h1>
.split {
position: relative;
display: inline-block;
font-size: 120px;
font-weight: bold;
color: black;
}
.split::before {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
width: 50%;
overflow: hidden;
color: transparent;
text-shadow: none;
background: white;
}
A more practical version uses two colors:
<h1 class="half-text" data-text="HELLO">HELLO
Step by Step Execution
Consider this example:
<span class="half" data-text="B">B</span>
.half {
position: relative;
display: inline-block;
font-size: 100px;
color: black;
}
.half::before {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
width: 50%;
overflow: hidden;
color: red;
}
What happens step by step
- The browser renders the real
<span>text:B. - That base text is black because of
color: black. - The
::beforepseudo-element creates anotherBusing .
Real World Use Cases
This effect appears in many practical UI and design situations:
- Hero headings: split-color letters in landing pages
- Branding: logos or initials with two-tone styling
- Progress effects: reveal part of text during loading or animation
- Interactive hover states: change one side of text on hover
- Themed text overlays: show before/after states in the same word
- Generated badges or initials: dynamic text without image generation
Example: a site might show a title where the left half uses the brand color and the right half uses a neutral color.
Example: a game UI might animate a word being filled from left to right using a clipped duplicate layer.
Real Codebase Usage
In real projects, developers usually use one of these patterns:
1. Pseudo-element overlay
This is common when the text is available in HTML and the effect is decorative.
Pattern:
- base text in normal color
::beforeor::afterduplicates text- clipped width or mask creates the visible half
2. Gradient text
This is common for simpler two-color splits.
Pattern:
background: linear-gradient(...)color: transparentbackground-clip: text
3. JavaScript for dynamic content
If the text changes dynamically and you cannot safely duplicate it in a data attribute manually, JavaScript can sync the attribute.
<h1 class="half-text" id="title">Dynamic</h1>
.half-text {
position: relative;
display: inline-block;
font-size: ;
: ;
}
{
: (data-text);
: absolute;
: ;
: ;
: hidden;
: ;
}
Common Mistakes
1. Expecting CSS to select half a character directly
Broken idea:
letter-half {
color: red;
}
There is no CSS selector or property that targets half of a glyph.
2. Forgetting to duplicate the text
Broken code:
.half::before {
position: absolute;
width: 50%;
overflow: hidden;
color: red;
}
Without content, the pseudo-element shows nothing.
Fix:
.half::before {
content: attr(data-text);
}
3. Not setting position: relative on the parent
Broken code:
.half::before {
position: absolute;
top: 0;
left: 0;
}
Comparisons
| Approach | Best for | Pros | Cons |
|---|---|---|---|
| Pseudo-element overlay | Dynamic text with a split effect | Works with real text, flexible, easy to animate | Requires duplicated text |
Gradient with background-clip: text | Simple two-color split | Clean and short CSS | Browser support details may matter |
| SVG text + clip/mask | Precise design control | Exact clipping, strong animation options | More complex markup |
| Image | Static artwork | Predictable appearance | Not ideal for dynamic text, scaling, or accessibility |
Pseudo-element vs gradient
| Feature | Pseudo-element |
|---|
Cheat Sheet
- CSS cannot directly style half of a single glyph.
- To create the effect, use two visual layers of the same text.
- Common solution:
- base text
::beforeduplicatewidth: 50%overflow: hidden
- For simple split color, use:
background: linear-gradient(to right, red 50%, black 50%);
color: transparent;
-webkit-background-clip: text;
background-clip: text;
- For overlay method, remember:
.parent {
position: relative;
display: inline-block;
}
.parent::before {
content: attr(data-text);
position: absolute;
inset: 0;
width: 50%;
overflow: hidden;
}
- If text is dynamic, sync it:
element.. = element.;
FAQ
Can CSS directly style half of a letter?
No. CSS cannot target half of a character as a separate text unit. You must simulate the effect.
What is the easiest way to make half a letter a different color?
Usually a text gradient with background-clip: text is the simplest approach for a clean 50/50 color split.
How do I do this with dynamic text?
Use real text in the DOM and copy its value into a data-text attribute with JavaScript if you are using a pseudo-element overlay.
Is JavaScript required?
Not always. CSS alone is enough if the text is already available in the markup or if a gradient effect is sufficient.
When should I use SVG instead of CSS?
Use SVG when you need exact clipping, masks, complex animation, or more reliable design precision.
Is using images a good solution?
Usually no for dynamic text. Images are less flexible, harder to maintain, and not ideal for accessibility.
Why does my split not perfectly match the letter shape?
Because most CSS clipping techniques split the element's box, not the true outline of the glyph.
Mini Project
Description
Build a dynamic two-tone heading component that displays text where the left half is one color and the right half is another. This demonstrates the common real-world technique of duplicating text with a pseudo-element and clipping the top layer.
Goal
Create a reusable heading that can display any dynamic text with a clean half-and-half color effect.
Requirements
- Display a heading using real text in the DOM
- Show the left half in a different color from the right half
- Support dynamic text updates with JavaScript
- Avoid using images
- Keep the text readable even if the effect is not supported
Keep learning
Related questions
Adding Table Rows with jQuery: append(), Limits, and Best Practices
Learn how to add table rows in jQuery using append(), what elements are allowed in tables, and safer ways to build rows dynamically.
Bower vs npm: What’s the Difference in JavaScript Package Management?
Learn the plain difference between Bower and npm, how each manages packages, and why npm replaced Bower in most JavaScript projects.
Can `(a == 1 && a == 2 && a == 3)` Ever Be True in JavaScript?
Learn how JavaScript type coercion, loose equality, and custom object conversion can make `a == 1 && a == 2 && a == 3` true.