18

I really like the look of two-tone buttons and fonts. I am thinking of when the top half of the font is one color and the bottom half is a variation on the same color. For an example see most of the buttons on an iPhone or the logo here http://ming.ly.

mingly

Is it possible to recreate this effect in CSS? Alternately is there a free tool I can use to generate fonts that look like this?

alex
  • 479,566
  • 201
  • 878
  • 984
Kevin Burke
  • 61,194
  • 76
  • 188
  • 305

2 Answers2

27

I managed to achieve that with CSS...

Example

Example

CSS

div {
    position: relative;  
    color: #0f0;
    font-size: 28px;
}

div span {
    height: 50%;
    position: absolute;
    color: #f00;
    overflow: hidden;  
}

HTML

<div>
    <span>Hello</span>
    Hello
</div>

jsFiddle.

Tested in Firefox 5.

Keep in mind that it is not very semantic to repeat the text to be displayed once.

Depending on the browsers you need to support, you could ditch that inner span for something like this in the CSS...

div:before {
    content: "Hello";
    height: 50%;
    position: absolute;
    color: #f00;
    overflow: hidden;   
}

jsFiddle.

As far as I know, there is no value for content which will automatically use that element's text node. You could put it on the title attribute and use attr(title) (or any other attribute).

You could also use JavaScript to do the repeating.

var textRepeat = document.createElement('span'),
    textRepeatTextNode = document.createTextNode(element.firstChild.data);

element.appendChild(textRepeat.appendChild(textRepeatNode));

If the first child was not necessarily a text node, you could use element.textContent || element.innerText.

alex
  • 479,566
  • 201
  • 878
  • 984
  • that's cool. Even if it's not great semantically. Could probably create javascript to automate it based on class, maybe. – yitwail Jun 27 '11 at 05:41
  • 2
    @yitwail Yeah, repeating it twice kinda sucks. You could always do `div:after { content: 'Whatever' }` in the CSS. – alex Jun 27 '11 at 05:42
  • I didn't even know you could do that, but then you're repeating it in css instead of html, it's still repeated. No need for that with JavaScript, but of course JavaScript may be unavailable. :( – yitwail Jun 27 '11 at 05:50
  • I realise it is probably useless to ask but could the downvoter explain their reasoning? I'd like to take the opportunity to learn something or defend my CSS :) – alex Jun 27 '11 at 05:51
  • @yitwail True, but as you can see there are downsides to most implementations. – alex Jun 27 '11 at 05:51
  • Do you think it would hurt Google juju to have the same text twice in a row? – Kevin Burke Jun 27 '11 at 05:53
  • @Kevin Possibly. Try one of the alternate solutions if that worries you. – alex Jun 27 '11 at 05:57
  • You can also retrieve the content from an attribute on the element via `content: attr(title)`. This would be slightly more semantic (and a lot more dynamic/flexible in my opinion). See [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/content) – Iolo May 06 '14 at 16:52
  • Yeah, it wasn't well supported in 2011 when I wrote the answer :) – alex May 07 '14 at 00:14
11

I like @alex method very much. An alternative solution, supporting the white curve, but not cross browser I suppose* at the moment, could be the following:

css

#text {
    color: #5283CA;
    font-size: 70px;
    height: 100px;
    overflow: hidden;
    width: 210px;
}
#curve {
    -moz-transform: rotate(60deg);
    -webkit-transform:rotate(60deg);
    -o-transform:rotate(60deg);
    -ms-transform:rotate(60deg);
    background: none repeat scroll 0 0 white;
    border-radius: 200px 20px 80px 20px;
    bottom: 270px;
    display: block;
    height: 1000px;
    opacity: 0.5;
    filter: alpha(opacity=50);
    position: relative;
    right: 330px;
    width: 200px;
}

html

<div id="text">Mingly<div id="curve"></div>

Demo: http://jsfiddle.net/ENPnU/

I don't know any css property that can make a border curved. So I used, the rounded corners that I can create with css. Then I rotate the element with rounded corners (in this case the #curve) to the correct position, to seems like a white curve within the text. Then white opacity added.

*I tried it to make it work with ie, but I didn't find a complete solution, you can find the result here: http://jsfiddle.net/3TpeA/

Sotiris
  • 38,986
  • 11
  • 53
  • 85