Advertisement


Is it possible to create a kind of horizontal "invert mask" in CSS?


Question

I have two blocks (div elements) with one black on the top background-color: black and one white on the bottom.

Is it possible to have a piece of text that straddles the two zones with inverted colors?

For example: the top part of the text "FOO" will be white on black and the bottom part black over a white region.

2014/05/20
1
7
5/20/2014 12:51:00 PM

Accepted Answer

If you mean something like this:

enter image description here


Edit: here's a way which only requires one HTML element and so won't be weird when read by non-CSS-styling clients like search engines, screen readers, RSS, 'no style' apps etc (thanks to Dominic for suggesting trying :before and :after).

http://jsbin.com/UtUlIFO/2/edit

The important code (add your colours to this):

HTML: <div class="someclass" data-text="Some text">Some text</div>

CSS:

.someclass {     /* bottom half */
  position: relative;
  display: inline-block;
}

.someclass:after {     /* top half */
  content: attr(data-text);
  display: block;
  position: absolute;
  top: 0px;
  height: 50%;
  overflow: hidden;
}

The HTML attribute can be anything - I used data-text because it's descriptive and avoids undesirable side effects (e.g. you could use title but it would create mouseovers in some browsers).

If you want display:block; on the main (.top) element, add something like width: 100%; to the inner (.bottom) element so it fills it.

If you're using jQuery, you can apply this style to any element really easily, avoiding having to manually type out the data-text duplicated bit:

$('.someElement').each(function(){
  $(this).addClass('someclass').attr('data-text',$(this).text());
});

Demo of that plus some other stuff like multiple lines, padding

10
5/20/2014 6:51:00 PM

Surprisingly, it is possible, though I'd only advise it if you're website is all about the visual impact and the semantics of the code don't matter, additionally it probably won't be very consistent across older browsers.

The result is:

Inverted Text

This is not a pretty solution, and I'd bet it's not the only one out there, but it does what you want.

It requires that you have two instances of the text, and using absolute positioning and some simple maths, you can create this effect.

So if we have a container div, and within that two more divs, and within each of those an instance of the text, you can use the following HTML structure and CSS properties to achieve this:

<div class="container">
    <div class="black">
       <div class="text">Invert</div>
    </div>
    <div class="white">
       <div class="text">Invert</div>
    </div>
</div>

.container{position:relative; width:200px; height:100px; display:block; margin:0px; padding:0px; }

.black, .white{position:absolute; left:0px; background:#000; width:200px; height:50px; margin:0px; padding:0px; overflow:hidden; }

.black{top:0px; }

.white{bottom:0px; background:#fff; }

.text{position:absolute; color:#fff; font-size:70px; padding:0px; }

.black .text{bottom:-40px; }

.white .text{top:-40px; color:#000; }

Here is a JSFiddle of the result. :)

2013/10/10