CSS formatting

Michael Bucks:

@desandro @simurai How do you guys format complicated gradient, box shadow, keyframe, etc. CSS3 attributes? I’m digging myself a hole here.

Been thinking about formalizing a style guide for CSS as CSS3 includes some especially complex syntax. Here’s how I’ve been playing this tune lately.

My preference is towards improving readability and scan-ability, if at the cost of length.

Lots of spaces

Taken from the jQuery Style Guide. Spaces inside parentheses so values can be easily read.

-webkit-transform: rotateX( 45deg ) translate( 100%, 0% );
background-color: hsla( 220, 100%, 50%, 0.7 )

Stagger vendor pre-fixed properties

Values for the same property should line up across declarations. This is a win for debugging as it makes it easier for glance at all the values and ensure that they are the same. Also good if you want to change them fast. With a visual cascade, you can quickly group the properties together see where the next one begins.

I made a couple TextMate snippets for this sort of thing.

-webkit-border-radius: 10px;
   -moz-border-radius: 10px;
        border-radius: 10px;
-webkit-transition: opacity 1s;
   -moz-transition: opacity 1s;
     -o-transition: opacity 1s;
        transition: opacity 1s;

Use white space to line up similar values

Again, makes it easier to debug and read. Typically good for animation keyframes

@-webkit-keyframes spinCube {
    0% { -webkit-transform: rotateX(   0deg ) translateZ( 100px ); }
   50% { -webkit-transform: rotateX(  90deg ) translateZ(  50px ); }
  100% { -webkit-transform: rotateX( 180deg ) translateZ(   0px ); }
}

Line breaks and tabs inside complex values

Usually in multiple backgrounds, gradient backgrounds, and multi-layered text-shadows. This looks a bit ridiculous because we’re so used to simple values. But if anyone else has to dive into a multiple-background with multiple gradients value, they can easily go in and start tweaking it. I might be going a bit overboard with white space for the WebKit color-stops.

background:
  -webkit-gradient( linear, left top, left bottom,
    from(            hsla( 0, 0%, 100%, 0.1 ) ), 
    color-stop( 50%, hsla( 0, 0%, 100%, 0.2 ) ),
    color-stop( 50%, hsla( 0, 0%,   0%, 0.0 ) ),
    to(              hsla( 0, 0%,   0%, 0.2 ) )
  ),
  -webkit-gradient( linear, left top, left bottom,
    from( hsl( 220, 100%, 60% ) ), 
    to(   hsl( 220,  80%, 60% ) )
  )
;
background:
  -moz-linear-gradient( -90deg,
    hsla( 0, 0%, 100%, 0.1 ), 
    hsla( 0, 0%, 100%, 0.2 ) 50%,
    hsla( 0, 0%,   0%, 0.0 ) 50%,
    hsla( 0, 0%,   0%, 0.2 )
  ),
  -moz-linear-gradient( -90deg,
    hsl( 220, 100%, 60% ), 
    hsl( 220,  80%, 60% )
  )
;

CSS gradients do not require starting or ending colors

CSS gradients do not require starting or ending colors. Without a starting or ending color-stop, the closest color-stop will apply to the end of the gradient.

View test fiddle

Multiple borders with box-shadow

I’m working on some comps that have two sets of borders. I’m solving for this by hacking box-shadows to produce multiple borders.

Test fiddle

The trick is to use the spread parameter of the box-shadow property to create bigger shapes than the original element.

The fourth length is a spread distance. Positive values cause the shadow shape to expand in all directions by the specified radius.

Note that like multiple backgrounds, box-shadows are rendered in reverse order. So the last shadow declared in the code will appear behind its predecessors. The first shadow appears at the top.

Interesting in how Firefox and Opera renders border-radius the faux-borders around the original element producing circles, whereas WebKit applies the original border-radius to the faux-borders, producing rounded rectangles.

Google Instant Preview

This deserves more research and tests.

Renders

  • 2D transforms
  • border-radius, elliptical border-radius
  • text-shadow
  • gradients

Does not render

  • 3D transforms
  • Typekit or @font-face
  • canvas

desandro.com Google Instant Preview

sxsw.beercamp.com Google Instant Preview

desandro conan Google Instant Preview

rumpetroll Google Instant Preview

attr funtion

Discovered the attr() function via Divya Manian superb CSS Vocabulary article.

CSS2

In CSS2, you can use attr() function to generate content inside :before and :after pseudo-elements.

<style>#attr-fn-demo:after { content: attr(id); background: yellow; }</style>

<p id="attr-fn-demo">The id of this element is: </p>

The id of this element is:

CSS3

The CSS3 implementation takes it to a whole new level. One can pull the value of an element’s attribute, add a unit, and it returns as a string inside a declaration.

It’s perfect for tag clouds, bar graphs, and a myriad of other applications. magine, if you will, using the value from an element’s data-popularity attribute to control its opacity.

<style>
  .tag { opacity: attr( data-popularity ); }
</style>

<div class="tag" data-popularity=".85">Foo</div>
<div class="tag" data-popularity="1.0">Bar</div>
<div class="tag" data-popularity=".7">Baz</div>

Sadly, no browsers support this AWESOME feature at the moment (confirmed with Ms. Manian).

Test fiddle using the example from Oxygen XML

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);
}

Opera Transform Issues

Couple issues with Opera’s current implementation of CSS transforms. I’m looking at this with version 10.62

  • Re-renders texts with poor anti-aliasing
  • A space in the value of transform functions will be thrown. So scale( 0.5) will not work, but scale(0.5) will. This goes for any transform function, translate(), rotate(), etc.

Live example:

-o-transform: translate( 20px, 10px) Value function has leading space. Transform will not be recognized. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

-o-transform: translate(20px, 10px) No leading space. Transform re-renders text with poor anti-aliasing. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Screenshot:

Discovering multiple text shadows

Mother Effing Text Shadow

Today, Paul Irish released mothereffingtextshadow.com. In typical Paul Irish fashion, it is a remarkable delight. Mr. Irish was kind enough to leave a comment in the markup:

all <3 goes to david desandro, who popularized this and many other amazing things.

The <3 is felt, bro.

But if anyone deserves <3, it would be David Cole. I first found the technique employed in his work for Sleepover’s Chunky Tumblr theme. Mr. Cole’s original implementation generated a triple offset border, an incredible innovation. While numerous others have picked up on my derivatives, I rarely see anyone use text-shadow the way he first did.

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