Categories
Tips

Cleanest CSS spinner, ever

For some reason, I seem to have a fascination with CSS loaders these days. After recreating the Google loader with clean CSS recently, I set off to recreate the classic spinner with CSS. Yes, I know this has been done zillions of times, but I wanted a clean, maintainable, reusable solution, not just a proof of concept. Something with not tons of CSS and/or HTML elements.

I managed to recreate it with only 2 elements. I’m still not completely satisfied, as I was hoping to come up with a solution with just one element, but it’s still much better than all those solutions out there that use tons of elements and code.

So, how did I do it?

  • I use the ::before and ::after pseudoelements of the parent and child div to create the 4 first bars
  • I use box-shadow with no blur on all four of the above to create the remaining 4 bars
  • I rotate the whole element with a steps(8) timing function to create the animation

As with the Google-style loader, just changing the font-size on this scales the whole element, as everything is sized with ems. Also, there is fallback text, to make it accessible to screen readers. Tested in Chrome, Firefox, Safari, IE10. Should degrade gracefully on IE9 (spinner should look fine, just no animation).

Using a preprocessor for variables and calculations should simplify the code even further.

Enjoy 🙂

Ideas for further improvement are welcome. Remember that it’s not just the size of the code that matters, but also its simplicity.

Categories
Tips

Flexible Google-style loader with CSS

So, for a while I had noticed the nice sutble loader Google apps use and I was wondering if it would be easy to make with CSS and CSS animations: Google’s loader

Yesterday, I realised that you can get this effect by increasing border size until about the middle of the element, as long as the total width stays the same (by using box-sizing: border-box):

However, as you can see above, after the midpoint, the border is not curved any more, so does not produce the desired effect. However, what if we split the background colour in half, and animated border-left until 50% of the width and then border-right from 50% of the width? That worked, but only gave us 25% of the effect. I could recreate the whole effect by then animating border-top/bottom instead etc, but it’s easier to apply animation-direction: alternate to alternate between showing and hiding the circle and and simultaneously rotate the loader by 90deg each time, by applying animation-timing-function: steps(4) to a rotate animation that runs over 4x the duration of the border animation.

This is the finished result:

The dimensions are all set in ems so that you can change the size in one place: Just change the font-size and the loader scales perfectly. It’s also accessible to screen reader users, as there is still text there.

And yes, it’s not super useful as-is, there are tons of spinners on the Web that you can use instead. However, I decided to post it (instead of just tweeting it) as I thought the techniques involved in making it might be interesting for some of you 🙂

Categories
Tips

Slanted tabs with CSS 3D transforms

Not sure if I’m the first to come up with this idea, but I searched and didn’t find anything. So, for a long time, I was wondering if there’s an easy way to create trapezoid shapes in CSS, especially with borders etc. Eventually, I realized that I could use a pseudo-element for the background and 3D rotate it, so that it appears like a trapezoid. Then @krofdrakula suggested on twitter that I could even add border-radius so that it looks like a tab, so I added that as well:

Eventually I thought, why not actually turn this into a tab demo? So I made a dabblet with that. And then I realized that if you change the transform-origin, other interesting tab shapes appear! Enjoy:

The best part? It degrades pretty gracefully on browsers that don’t support transforms! You get nice rounded tabs that just aren’t slanted (although they have a pretty large top padding, but you can use Modernizr for that. Try it for yourself by commenting the transform out in the dabblet and see the result.

Another issue is that the angled lines look a bit aliased in Firefox, but that’s a bug that will eventually get fixed.

In general, it’s a bit rough around the edges, so treat it more as a proof of concept. But with a little more work, it could totally work in production. Tested in Chrome, Safari, Firefox, IE9 (fallback) and IE10.

Categories
Original Tips

Easily center text vertically, with SVG!

These days, we have a number of different ways to vertically align text in a container of variable dimensions:

  • Table display modes
  • Flexbox
  • inline-block hacks
  • Wrapping the text in an extra element and absolutely positioning it
  • …and probably many others I’m forgetting

However, often comes a time when neither is suitable, so here I am, adding yet another option to the list. Of course, it comes with its own set of drawbacks, but there are cases where it might be better than the existing solutions.

Categories
Tips

Use MathML today, with CSS fallback!

These days, I’m working on the slides for my next talk, “The humble border-radius”. It will be about how much work is put into CSS features that superficially look as simple as border-radius, as well as what advances are in store for it in CSS Backgrounds & Borders 4 (of which I’m an editor). It will be fantastic and you should come, but this post is not about my talk.

As you may know, my slides are made with HTML, CSS & JavaScript. At some point, I wanted to insert an equation to show how border-top-left-radius (as an example) shrinks proportionally when the sum of radii on the top side exceeds the width of the element. I don’t like LaTeX because it produces bitmap images that don’t scale and is inaccessible. The obvious open standard to use was MathML, and it can even be directly embedded in HTML5 without all the XML cruft, just like SVG. I had never written MathML before, but after a bit of reading and poking around existing samples, I managed to write the following MathML code:

Categories
Tips

CSS Animations with only one keyframe

This is a very quick tip, about a pet peeve of mine in almost every CSS animation I see. As you may know, I’m a sucker for reducing the amount of code (as long as it remains human readable of course). I demonstrated a very similar example in my “CSS in the 4th dimension” talk, but I recently realized I never blogged about it (or seen anyone else do so).

Lets assume you have a simple animation of a pounding heart, like so:

Categories
Tips

Hacking lookahead to mimic intersection, subtraction and negation

Note: To understand the following, I expect you to know how regex lookahead works. If you don’t, read about it first and return here after you’re done.

I was quite excited to discover this, but to my dismay, Steven Levithan assured me it’s actually well known. However, I felt it’s so useful and underdocumented (the only references to the technique I could find was several StackOverflow replies) that I decided to blog about it anyway.

If you’ve been using regular expressions for a while, you surely have stumbled on a variation of the following problems:

  • Intersection: “I want to match something that matches pattern A AND pattern B”
    Example: A password of at least 6 characters that contains at least one digit, at least one letter and at least one symbol
  • Subtraction: “I want to match something that matches pattern A but NOT pattern B”
    Example: Match any integer that is not divisible by 50
  • Negation: “I want to match anything that does NOT match pattern A”
    Example: Match anything that does NOT contain the string “foo”

Even though in ECMAScript we can use the caret (^) to negate a character class, we cannot negate anything else. Furthermore, even though we have the pipe character to mean OR, we have nothing that means AND. And of course, we have nothing that means “except” (subtraction). All these are fairly easy to do for single characters, through character classes, but not for entire sequences.

However, we can mimic all three operations by taking advantage of the fact that lookahead is zero length and therefore does not advance the matching position. We can just keep on matching to our heart’s content after it, and it will be matched against the same substring, since the lookahead itself consumed no characters. For a simple example, the regex /^(?!cat)\w{3}$/ will match any 3 letter word that is NOT “cat”. This was a very simple example of subtraction. Similarly, the solution to the subtraction problem above would look like /^(?!\d+[50]0)\d+$/.

For intersection (AND), we can just chain multiple positive lookaheads, and put the last pattern as the one that actually captures (if everything is within a lookahead, you’ll still get the same boolean result, but not the right matches). For example, the solution to the password problem above would look like /^(?=.*\d)(?=.*[a-z])(?=.*[\W_]).{6,}$/i. Note that if you want to support IE8, you have to take this bug into account and modify the pattern accordingly.

Negation is the simplest: We just want a negative lookahead and a .+ to match anything (as long as it passes the lookahead test). For example, the solution to the negation problem above would look like /^(?!.*foo).+$/. Admittedly, negation is also the least useful on its own.

There are caveats to this technique, usually related to what actually matches in the end (make sure your actual capturing pattern, outside the lookaheads, captures the entire thing you’re interested in!), but it’s fairly simple for just testing whether something matches.

Steven Levithan took lookahead hacking to the next level, by using something similar to mimic conditionals and atomic groups. Mind = blown.

Categories
Replies Tips

Text masking — The standards way

As much as I like .net magazine, I was recently outraged by their “Texturizing Web Type” article. It features a way to apply a texture to text with -webkit-mask-image, presenting it as an experimental CSS property and misleading readers. There are even -moz-, -o- and -ms- prefixes for something that is not present in any specification, and is therefore unlikely to ever be supported by any non-WebKit browser, which further contributes to the misdirection. A while back, I wrote about how detrimental to our work and industry such proprietary features can be.

A common response to such complaints is that they are merely philosophical and who cares if the feature works right now and degrades gracefully. This argument could be valid for some cases, when the style is just a minor, gracefully degrading enhancement and no standards compliant alternative is present (for example, I’ve used ::-webkit-scrollbar styles myself). However, this is not the case here. We have had a standards compliant alternative for this for the past 11 years and it’s called SVG. It can also do much more than masking, if you give it a chance.

Categories
Tips

Pure CSS scrolling shadows with background-attachment: local

A few days ago, the incredibly talented Roman Komarov posted an experiment of his with pure CSS “scrolling shadows”. If you’re using Google Reader, you are probably familiar with the effect:

Screenshot demonstrating the “scrolling shadows” in Google Reader

In Roman’s experiment, he is using absolutely positioned pseudoelements to cover the shadows (which are basically radial gradients as background images), taking advantage of the fact that when you scroll a scrollable container, its background does not scroll with it, but absolutely positioned elements within do. Therefore, when you scroll, the shadows are no longer obscured and can show through. Furthermore, these pseudoelements are linear gradients from white to transparent, so that these shadows are uncovered smoothly.

When I saw Roman’s demo, I started wondering whether this is possible with no extra containers at all (pseudoelements included). It seemed like a perfect use case for background-attachment: local. Actually, it was the first real use case for it I had ever came up with or seen.

Categories
Tips

Flexible multiline definition lists with 2 lines of CSS 2.1

If you’ve used definition lists (<dl>) you’re aware of the problem. By default, <dt>s and <dd>s have display:block. In order to turn them into what we want in most cases (each pair of term and definition on one line) we usually employ a number of different techniques:

  • Using a different <dl> for each pair: Style dictating markup, which is bad
  • Floats: Not flexible
  • display: run-in; on the <dt>: Browser support is bad (No Firefox support)
  • Adding a <br> after each <dd> and setting both term and definition as display:inline: Invalid markup. Need I say more?

If only adding <br>s was valid… Or, even better, what if we could insert <br>s from CSS? Actually, we can!