WebKit zoomed-out font-size threshold

The zoomed-out font-size threshold in WebKit is a mysterious anomaly I’ve long had my suspicions about, but now have finally tested. Take some body copy, start zooming out the page, and observe how copy with smaller font-sizes seem to maintain some legible size, even though they should be much smaller. Try hitting ⌘- too see the effect on this fiddle.

View fiddle - zooming font-size threshold

Here’s how Chrome 16 renders the fiddle with Zoom Out hit twice. Zoomed-out font-sizes 13px-9px are all rendered as the same size. Smaller font-sizes return to proper proportions. Note that this is not Safari’s preference to limit small font-size, as the teeny-tiny font-sizes are still rendered.

WebKit zoomed-out font-size threshold

Zooming out four times, it appears that the threshold is setting a font-size to 9px. Any text set to 9px font-size or greater will be rendered at least the minimally-legible size of 9px. Anything smaller will be rendered proportionally.

WebKit zoomed-out four times. Font-size 9px threshold

Resolving anti-aliasing on WebKit hardware-accelerated elements

Activating hardware acceleration in WebKit with 3D CSS transforms changes the way WebKit renders text. WebKit composites the element so that when rendering the transform, it doesn’t have to re-render sub-pixel anti-aliasing for every frame. This feature is a good thing in that vastly improves performance of transitions and transforms in WebKit.

But this affects anti-aliasing when there is no actual transform and hardware-acceleration is active on a element. i.e. banal 3D transforms like translate3d( 0, 0, 0) or scale3d( 1, 1, 1 ).

The solution is the same one for IE’s opacity bug: add a matching background to the affected background.

View fiddle: resolving anti-aliasing with hardware acceleration.

Hover over the image below to see the comparison for TUAW.

See also Webkit Hardware acceleration bleeding into subsequent elements, and how to fix it - The Official Posterous Tech Blog.

#color keyword values

WebKit parses #colorkeyword values as valid colors. background: #yellow renders as yellow.

#color fiddle

Being thorough, I also tested other color values with an extra # in front. No dice, only keywords get parsed.

Max border-width

Some browsers max-out border-width. In the fiddle below, where I set border-bottom-width: 9999px, WebKit browsers render only 1807px, Opera renders 2407px. Like a mad scientist, Firefox renders all ten-thousand-minus-one pixels.

Max border-width fiddle

WebKit Transform Perspective Function

Yar, 3D transform be ahead. Safari only. The examples below also live together in a lovely house in this fiddle.

Safari has support for a perspective transform function. This is pretty convenient for doing a simple 3d transform, like a card flip.

#wkptfn-example1 .alpha {
  background: blue;
  -webkit-transform: perspective(800) rotateY( 0deg);
}

#wkptfn-example1:hover .alpha {
  -webkit-transform: perspective(800) rotateY(-180deg);      
}

#wkptfn-example1 .beta {
  background: red;
  -webkit-transform: perspective(800) rotateY(180deg);
}

#wkptfn-example1:hover .beta {
  -webkit-transform: perspective(800) rotateY( 0deg);
}

Hover for Card Flippin’ Action

The problem with it is that the perspective is only for the one element. If you use the same transform across elements with different position, each element will have its own vanishing point.

#wkptfn-example2 div {
  -webkit-transform: perspective(800) rotateY(45deg);
}

To remedy this, you need to specify a perspective or the parent with -webkit-perspective: and then let the children inherit it with -webkit-transform-style: preserve-3d;

#wkptfn-example3 {
  -webkit-perspective: 800;
}

#wkptfn-example3 div {
  -webkit-transform-style: preserve-3d;
  -webkit-transform: rotateY(45deg);
}

-webkit-line-clamp

-webkit-line-clamp is an unsupported WebKit property that limits the number of lines of text displayed in a block element. In order to achieve the effect, it needs to be combo-ed with a couple of other exotic WebKit properties.

<p style="
  overflow : hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
">
  WebKit Browsers will clamp the number of lines 
  in this paragraph to 2. Lorem ipsum dolor sit amet, 
  consectetur adipisicing elit, sed do eiusmod tempor 
  incididunt ut labore et dolore magna aliqua. Ut enim 
  ad minim veniam, quis nostrud exercitation ullamco 
  laboris nisi ut aliquip ex ea commodo consequat. Duis 
  aute irure dolor in reprehenderit in voluptate velit 
  esse cillum dolore eu fugiat nulla pariatur. Excepteur 
  sint occaecat cupidatat non proident, sunt in culpa qui 
  officia deserunt mollit anim id est laborum.
</p>

WebKit Browsers will clamp the number of lines in this paragraph to 2. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Webkit 2-parameter border-radius

Recent WebKit browsers (I’m looking at Safari 5.0.1 and Chrome 6.0.472.36 beta) now adhere to the CSS3 border-radius spec, so you can drop the -webkit- vendor prefix. But conflict occurs when you use two parameters as the value.

.box {
  -webkit-border-radius: 40px 10px;
     -moz-border-radius: 40px 10px;
          border-radius: 40px 10px;
}

Firefox, Opera, and the latest WebKit browsers (and IE9, I’m guessing) will display a box with the top-left and bottom-right with 40px border-radius, and a top-right and bottom-left with a border-radius of 10px.

But older WebKit browsers will not have the new border-radius rule overwrite the previous -webkit-border-radius, and instead the box with have an eliptical border-radius, the equivalent of border-radius: 40px/10px;.

WebKit animation bounce easing

Getting a fluid bouncing animation can be tricky as you have to set the easing (otherwise known as -webkit-animation-timing-function) for each keyframe. Keep the physics of a bouncing ball in mind. As the object moves upwards, its acceleration decreases until it comes to the top of its accent. So going upwards, -webkit-animation-timing-function: ease-out. Returning downwards, acceleration increases due to gravity. Ergo, -webkit-animation-timing-function: ease-in.

Take a look at this example code:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>WebKit animation bounce easing</title>
  <meta charset="utf-8" />

  <style media="screen">

    h1 {
      position: absolute;
      left: 10px;
      top: 200px;
      -webkit-animation: bounce 1s infinite ;
    }

    @-webkit-keyframes bounce {
        0% { -webkit-transform: translate3d(0,   0px,0); 
             -webkit-animation-timing-function: ease-out; }
       50% { -webkit-transform: translate3d(0,-150px,0); 
             -webkit-animation-timing-function: ease-in; }
      100% { -webkit-transform: translate3d(0,   0px,0); }
    }

  </style>

</head>
<body>

  <h1>Bouncing</h1>

</body>
</html>

Note that the easing is being set on which keyframe. For the upward motion (0% - 50%) it is set on the initial keyframe. On the downward motion (50% - 100%), it is set on the 50% keyframe. The final keyframe requires no easing to be set as this is the final destination of the animation, with no motion occurring afterwards.

This example works in Safari 5. Chrome’s animation rendering engine (I’m looking at on 5.0.375.125 beta) currently looks glitchy.

using -webkit-background-size on iPhone 3GS and below, scaling images down to less than 50% of their original size won’t work.