Article Archives

New Poll: Your Internet Connection Speed

I think it would be interesting to get an idea of what the internet connection speeds are like for CSS-Tricks readers. Connection speed makes such a huge difference in the web browsing experience I hope that getting an understanding of what speeds people are getting will help us all kind that in mind when working on websites. (more…)

Numbering In Style

Chances are if you want to number things in order on a website, the ordered list (<ol></ol>) is your guy. It also is pretty reasonable that you want to style those numbers. Strangely enough, styling those list numbers isn't a very easy thing to in CSS. Thankfully it's also not impossible. (more…)

Relevant Dropdowns: Polyfill for Datalist

The list attribute / datalist element of HTML5 forms is pretty cool. As you type in a text input, it shows you a dropdown menu of choices you can pick from. Or you can type in whatever you want. The list attribute alone doesn't lock you into any specific value. In that way, it's a bit like a group of radio buttons with an "other" type-in option. (more…)

24 Ways: Unicode Range

24 ways, the annual all-thing-front-end-web advent calendar, kicks off this year with some very clever CSS trickery by the publications founder Drew McLellan.

The Script Tag

I got a great question from reader Josh Kreis:

I've noticed that on a <script></script> tag, there are all kinds of variations that all seem to work cross-browser. What is necessary and what isn't?


Simple Styles for Horizontal Rules

That is, the <hr /> element. With the help of a few contributors, I put together this page of very simple styles for them. You could get a lot fancier with an element like a <div></div> that can hold content, but I like the semantics of a horizontal rule. It's an emphatic break between two sections of content. (more…)


Kevin Dees interviewed me. We talked about all kinds of front-endy stuff, this site, and other fun stuff. (video)


I just added "The Big Three" sharing buttons to articles on this site: Twitter, Google Plus, and Facebook. I've shared my thoughts on sharing buttons like this in the past. I essentially decided that I didn't like them for this site. So before anybody skewers me for hypocrisy, I thought I'd go back through my old thoughts and refute myself.


Vendor Prefixes, yadda yadda yadda, strong opinions

Henri Sivonen:

I think vendor prefixes are hurting the Web. They are hurting Web authors. They are hurting users of browsers. They are hurting competition in the Web browser space.

I'm tempted to raise my fist in disagreement, but you know what, I'm not an oracle. I can't know the future nor know how the world would have turned out if we never used vendor prefixes.

Here's a guess though: if we were to go back in time and influence the decision such that browsers agreed to never use vendor prefixes, we would be worse off. Less browser innovation, less of the spec implemented, and more serious cross-browser problems when some browsers jump the gun and implement specs prematurely.

Vendor prefixes, while being an eyesore and requiring maintenance, have saved us from a dystopian present (maybe).

Five Questions with Tab Atkins

Tab Atkins (Twitter) is a member of the CSS working group and contributor to several other working groups in the W3C. He works for Google on the Google Chrome Team. Browsers and specs are the bones and blood of our industry so that makes Tab, uhm, a orthopedic surgeon, or something. I ask Tab about all that stuff, and more, below. (more…)

Yes/No Ipsum!

I've heard a number of people make statements lately like: "If you're using Lorem Ipsum text, just stop it." Or similar. That argument, expanded, goes something like this. Design exists to serve content. Lorem ipsum is fake content. If you're already designing, and you are using fake content, you are not serving the content and thus not doing your job as a designer correctly. (more…)

The Future, Glassy?

Bret Victor:

Now, take out your favorite Magical And Revolutionary Technology Device. Use it for a bit.

What did you feel? Did it feel glassy? Did it have no connection whatsoever with the task you were performing?


Mac users, this is really worth checking out. As you work on local projects, you have your HTML and CSS open in your text editor of choice, and the web page open in a browser. With LiveReload, as soon as you save files the changes appear in the browser (with CSS, it doesn't even need to reload the page). It also works with all the popular preprocessors and instantly compiles as you save. Might just change the way you work. I have a feeling it's going to change mine.

jQuery 1.7 Released

You'll probably start seeing .on() and .off() on tutorial sites so just a heads up, that's new syntax for event binding in jQuery (although all the old methods still work too).

Columns and the Greatest Common Divisor

I was recently putting together some CSS for columns. There was a few pre-determined widths that the columns needed to accommodate. For whatever reason (maybe because every grid framework in the world is this way) my mind went right to trying to find a common building block size. All columns are either the size of one building block or a multiple of a building block with gutter widths added. (more…)

Five Questions with Lea Verou

Lea is a front end web developer from Greece. You have likely heard of her, as ever since she started blogging in English (read more about that below), she's had quite a boom in popularity. Or perhaps you've seen some of her work. She's created a number of one-page sites that either show off amazing things CSS can do or help you with a difficult/tedious task.

I asked Lea some questions about critical reaction to her work, the community in Greece, the future of CSS, and more.


A Call for ::nth-everything

With CSS3, we have positional pseudo class selectors to help us select specific elements when there are no other distinguishing characteristics other than where it is in the DOM in relation to it's siblings.




We also get a couple of text-specific pseudo elements to help with our typography needs:


That's a great start, but it really would be useful if we could extend the whole ":nth" concept to these typographic selectors. Let me convince you.

Please note that most of the code below is not valid. It's example code. Like "wouldn't it be cool if" code.

::nth-line() / ::last-line / ::nth-last-line()

We already have ::first-line, so to complete the set let's add ::nth-line(), ::last-line, and ::nth-last-line().

With these, we could select the first two lines of a poem to highlight.

article.poem p:first-child::nth-line(-n+2) {
  font-variant-caps: small-caps;
  color: red;

I don't know from poetry, Brendon.

Or perhaps we could fade out the end of a passage.

article.poem p:last-child::nth-last-line(3) {
   color: hsla(26, 5%, 25%, 1);
   font-size: 70%;
article.poem p:last-child::nth-last-line(2) {
   color: hsla(26, 5%, 50%, 1);
   font-size: 60%;
article.poem p:last-child::nth-last-line(1) {
   color: hsla(26, 5%, 75%, 1);
   font-size: 50%

If we were allowed to use generated content on these line pseudo elements, we could accomplish something like line numbering without having to resort to intrusive markup.

pre::nth-line(n)::before {
  content: counter(line) ". ";
  color: #999;

Look ma, easy practical multi-line code styling.

Relevant article by Adam Prescott.

::nth-word() / ::first-word / ::last-word / ::nth-last-word()

We currently don't have any word-based pseudo elements. We do have word-spacing though, which is notable.

One use case is similar to using ::first-letter for drop caps, only doing a whole word.

article p::first-word {
  float: left;
  font-size: 300%;
  margin: 0 10px 10px 0;

Also similar to the "fade out" of lines above, we could fade out a passage word-by-word using ::nth-last-word(n).

::nth-letter() / ::last-letter() / ::nth-last-letter()

We already have ::first-letter, which sees pretty decent usage, so why not complete the set?

Of all of these "new" selectors, ::nth-letter is likely the most useful. For instance, Lettering.js wraps letters in <span>s for us so that we can select individual letters. This would be entirely unnecessary with ::nth-letter.

Take this example:

h1.fancy::nth-letter(n) {
  display: inline-block;
  padding: 20px 10px;
h1.fancy::nth-letter(odd) {
  transform: skewY(15deg);
  background: url(light-red-pattern.png);
h1.fancy::nth-letter(even) {
  transform: skewY(-15deg);
  background: url(dark-red-pattern.png);
h1.fancy::nth-word(n) {
  margin-right: 20px;
h1.fancy::last-word {
  margin-right: 0;

Check out all the examples at Lettering.js -- all of those are good examples of the need for this.

Another word/letter combination example is a formal "letter", like:

<p>Dear Emily,</p>
<p>yadda yadda yadda.</p>
<p>Love, Chris.</p>

Perhaps this "letter" is generated by dynamic content from a database, but we want to ensure the proper capitalization and style of the opening and closing lines.

.letter p:first-child::nth-word(-n+2)::nth-letter(1),
.letter p:last-child:nth-word(-n+2):nth-letter(1) {
  text-transform: uppercase;

The Complete Set

So if we get all of this, the complete set would be:

:first-child        :first-of-type        :only-child
:last-child         :last-of-type         :only-of-type                  
:nth-child          :nth-of-type    
:nth-last-child     :nth-last-of-type

::first-letter      ::first-line          ::first-word
::last-letter       ::last-line           ::last-word
::nth-letter        ::nth-line            ::nth-word
::nth-last-letter   ::nth-last-line       ::nth-last-word 

Again, just wishful thinking. If there is anyone I can put this in front of that can do something about it, I will. And I'll also keep this updated with the feedback on it, positive or negative.

For the record, this isn't a new request. Anne van Kesteren called for it in 2003.

Centering in the Unknown

When it comes to centering things in web design, the more information you have about the element being centered and its parent element, the easier it is. So what if you don't know anything? It's still kinda doable.


HTML5 for Web Designers Website

The content of HTML5 for Web Designers, the first A Book Apart book by Jeremy Keith, is online. Under the hood, the title bar at the top of the page is actually the <title> element, unhidden and styled up.

What We Don’t Know

We don't know which browser, which version of that browser, or what kind of computer a user visiting our website is using.

That's why we have web standards we follow which give us the ability to code one website that can work everywhere. We use normalized templates (e.g. HTML5 Boilerplate) to give our projects a consistent and healthy starting point. We use JavaScript libraries (e.g. jQuery) to make things easier for us an alleviate cross browser issues.

We don't know the capabilities of the browser the user is visiting our website with.

So we feature test and polyfill where we can. That way we can build the fantastic experience we want to and deliver perfectly acceptable experiences to all browsers.

We don't know what the size of browser window is of a user viewing our website.

So we should design our sites to be fluid and utilize media queries to optimize the site for any screen size (responsive web design).

We don't know what the internet connection speed is of a user viewing our website.

So we try and load as few resources as possible. We make those resources as small and compressed as we can. We serve those resources through servers optimized just for that and geographically closer to our users (e.g. NetDNA). That way our website loads as fast as possible.

We don't know the mindset of a user viewing our website.

So we conduct user research (e.g. Silverback) and try to find out. We try and accommodate different ones. We use our experience (and sometimes gut instinct as users ourselves) to make the right decisions. We design for humans.

We don't know the physical location of a user viewing our website.

So if our site needs it or could be better by knowing it, we can ask for it. Either literally or through HTML5.

We don't know what languages a visitor to our site understands.

So if we have the resources to do it, we use translation services (e.g. Smartling) to offer our website in a user's native tongue. If we are trying to be as professional as we can, we also probably try and be sensitive to culture differences worldwide.

We don't know how "computer savvy" a user is visiting our site.

So we try and make it very obvious how to use our site and not make too many assumptions. We use common design patterns to accommodate "affordances". We sweat the details in our design, copy, and overall "user experience".

We don't know what disabilities a user visiting our site might have.

So we try and craft our sites with accessibility in mind.


We know very little about a visitor to our website. We actually know less and less every day, as the demographics of internet users widens (younger and older, no longer a nerd thing, more areas geographically, etc.) So as we march forward toward the next 6 billion people using the web, let's embrace the unknown by accommodating for it.

Abbr’s for Web Nerd Acronyms

I'm really lazy about using <abbr></abbr> tags for acronyms. Most people who read a techy blog like this probably understand them, but surely there are some visitors who don't where a simple tooltip explanation would be beneficial. Maybe with this easy copy-and-paste resource to reference I'll actually start doing it. This is an education blog, after all. (more…)

CSS Shaders

A bunch of crazy awesome affects you can apply via CSS through the filter property: blur, drop-shadow, gamma, grayscale, hue-rotate, invert, opacity, saturate, sepia, and sharpen. Adobe has been doing some great stuff with CSS lately. Their last amazing demo isn't just a demo anymore, it will be implemented in IE 10. Let's hope these make it into the spec and implemented as well.


It's a new language the runs in the browser and servers. A lot of it is over my head, but I always celebrate new thinking especially when it has a bunch of smart people behind it. The obvious point is that, if it's a direct competitor to JavaScript, that JavaScript has far more browser support. I'm sure that fact isn't lost on the team.

Wasn't this the last Google-originated language? Did that go anywhere?

New Poll: Ideal Page Weight

Since that last post was kind of a bust (in a good way!) - let's kick off another one right away. We'll keep it along the same lines: page weight, this time regarding the page as a whole.

Way back in the day Google used to only index 100k of a page (although I think that's the HTML only) but that's not true anymore. 200k for the entire page (including all resources: css, images, js, etc) used to be a common goal. I'd say very few web pages these day come in at under 200k.

The CSS-Tricks homepage right now weighing in at 607k

So the new poll is:

What do you think is reasonable page size to try and stay under for a modern web design?

Full, real time results for this poll and all post polls are in the polls archive.

Making SublimeVideo Fluid Width

Since v9 of this site, I've been using SublimeVideo for the video player in the screencasts area. SublimeVideo is similar to projects like VideoJS and MediaElement.js in that it's a polyfill for HTML5 video. That is, you use regular ol' clean HTML5 <video> markup and it takes care of making sure that video can be seen on as many browser/platform/versions as possible.

How does SublimeVideo differ from those other projects?

  • They host the resources, not you. That means some bandwidth savings, but more importantly, means that you're always getting the latest and greatest version which is important in this fast-changing browser landscape.
  • It's the nicest design of all of them. Subjective, I suppose.
  • It's not free. While the others are.

I quite like the idea of paying for services that make our lives as front end developers easier, so I hopped on board (I pay for the service on the Star plan).

Do note that SublimeVideo is for video that you host yourself somewhere. They don't host video for you. If you want hosted video and a player that similarly works everywhere without worrying about bandwidth, you should probably just use YouTube, Vimeo or

Using SublimeVideo regularly, you simply load their JavaScript in the <head>:

<script src="//"></script>

Then use HTML5 video like this:

<video class="sublime" width="640" height="360" poster="video-poster.jpg" preload="none">
  <source src="//" />
  <source src="//" />

This works great, but the resulting video player is of a static width and height. In a fluid width / responsive site like I have here media of fixed dimensions don't play well. I'd much rather the video shrink and grow with the column that it's inside of as needed.

I've tackled the idea of fluid width video a number of times around here. Ultimately I helped with FitVids.js, a jQuery plugin for easily making videos from all the most popular sources work in fluid width designs. Unfortunately FitVids.js doesn't work with SublimeVideo. For lack of a better explanation, they are just different beasts and making them work together would be more trouble than it's worth.

Good news though, after a bit of pleading (I'm sure they had lots of requests for this) they released a new bit of API specifically for resizing. So making the video fluid width is as easy as watching for the window.resize event, and when that fires, calculate the new width and height and use the sublimevideo.resize function to change it.

This is the full code I use. There is a few extra bonus bits in there explained via code comments. Note this uses a bit of jQuery. Also note the "sublime" class on the <video> element is removed.

<video id="the-video" width="570" height="320" poster="poster.jpg" controls preload="none">

(function() {

  // Prevents some flickering
  $('#the-video').css("visibility", "hidden");

  // Fluid column video is inside of
  var fluidParent = $(".main-column"),
  newWidth, newHeight;

  // Gets called when video needs resizing
  function resizeVideo() {
    newWidth = fluidParent.width();
    // 1.78125 == Aspect Ratio of my videos
    sublimevideo.resize('the-video', newWidth, newWidth/1.78125);

  $(window).resize(function() {

  // When the resources are ready, 
  // load up the video and size it correctly
  sublimevideo.ready(function() {


If you'd like to see it in action you can see it on single video pages.

Building a Starburst with CSS

If there's one thing I love most about what I do it's building out the challenges that a designer throws my way. There's almost always a way to reproduce a design in code, and I love figuring out how to get as close to the original design as possible with CSS. (more…)