Take the 2-minute tour ×
Graphic Design Stack Exchange is a question and answer site for Graphic Design professionals, students, and enthusiasts. It's 100% free, no registration required.

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.

share|improve this question
1  
Related and useful: Is it possible to apply CSS to half of a character? and one of the best answers to the q as a plugin: Splitchar - this plugin also does what is asked for on this page, yet it can also do 3 levels of colour horizontally or vertically. –  Mr E. Upvoter May 20 at 12:55

3 Answers 3

up vote 10 down vote accepted

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

share|improve this answer
2  
I'm trying to figure out if there's a way to do it by creating the duplicate text with a pseudo-element (:after or :before) any ideas? –  Mr E. Upvoter Oct 10 '13 at 17:37
2  
Interesting idea: you can do this (duplicating the content hard-coded into the CSS) or this (duplicating the content in a HTML attribute, then reading that) but apparently it's not possible to simply read the HTML content text using CSS. The HTML attribute way seems the best since it doesn't mess up machine-reading of the HTML. I've added some things like this above. –  user568458 Oct 11 '13 at 9:35

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. :)

share|improve this answer
    
Oooh posted while I was finishing typing! Nice answer but I think there's a couple of ways it can be simplified to be more something that can be dropped in anywhere. I think there's no way to do it without duplicating text. –  user568458 Oct 10 '13 at 17:05
1  
Haha! I was rushing to get it in before somebody else :P! It's surprising how easy it was. That said, you're answer has waaay less code. I'd go with your one if it was me choosing. –  Mr E. Upvoter Oct 10 '13 at 17:10

There is also a CSS3 property, only supported by webkit, that inverts colors:

image {
 -webkit-filter: invert(100%);  
}

And there's an HTML5 Canvas Invert, here's an example and the full code. It iterates over all of the pixels in an image and inverts red, green, and blue by subtracting each component from the max color value, 255.

Both solutions would still require 2 images and CSS positioning for them. Since compatibility is not very good, I'd definitely go for one of the other answers :)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.