Article Archives

The CSS Standards Process

The following is a guest post by Sebastian Ekström (@seb_ekstrom) a web developer from Sweden. I was interested in it because we talk a lot about CSS around here but have never talked about how CSS comes to be. CSS is just a syntax invented by people like you and me to try and solve problems. It's an extremely complicated thing involving: ease of use, backwards compatibility, browsers ability to implement with satisfactory speed, coverage of use cases, attempting to see the future of what is needed and how things may be used, and more. As we well know, bad choices hurt, and hurt for a long time. That's why there is a process. Here is Sebastian's intro to that process. I had Tab Atkins review it and comment prior to publication.

(more…)

CSSOff 2013

It's live!

If this is the first you've heard of it, it's a contest where you get a Photoshop document and have two weeks to convert it into HTML and CSS. You're judged on an established set of criteria.

The design this year is by Daniel Mall.

You have to submit your design through CodePen. As you'll need to host files (like images) to make it happen, and you'll want to be working privately, you'll need a CodePen PRO account, which you can have for free for the duration of the contest. Just log in and then go here and get the free upgrade.

HTML Imports

Essentially a way to import a block of dependancies (scripts and styles) into an HTML document.

<link rel="import" href="imports.html">

It doesn't actually just plop the content from the referenced file where you call it though, like an @import does in CSS or and include does in a server side language. HTML could very much use that.

-moz-gone

Mozilla says they "will no longer ship new 'moz'-prefixed APIs" as part of an overall philosophy of: "Is this good for the Web?"

Blink has also said this. Word has it WebKit still plans to use them as they deem necessary.

A Guide to Web Components

The following is a guest post by Rob Dodson (@rob_dodson). Rob and I were going back and forth in CodePen support getting Polymer (a web components polyfill, kinda) working on a demo of his. We did get it working, and things kind of evolved into this article. Take it away Rob.

Update: Rob updated this article on March 5, 2014, getting everything up to date, as this is a rather fast-moving technology at the moment.

Update: Updating again September 9, 2014!

(more…)

Transformer Tabs

Tabs are a simple design pattern in which a row of links are obviously clickable navigation and when a link is clicked, new content is shown. There are loads of variations of course, but it's one of the most ubiquitous navigation design patterns out there. When arranged in a horizontal row, it is also one of the least small-screen-friendly design patterns out there.

We can make it work though.

(more…)

Bookmarklet to Colorize Text Between 45 and 75 Characters (for line-length testing)

Recently at the CSS Dev Talk, I attended Clarissa Peterson's talk on responsive web typography. One part of it was about line length and readability. Of course, there are exceptions to every rule and your mileage may vary, but the traditional thinking is that body copy (long text, multiple paragraphs, takes more than a glance to read...) should be between 45 and 75 characters per line to be comfortable. Shorter is awkward, longer makes it easy to lose your place and find the next line.

In a world of fixed width designs, getting that text to be between 45-75 characters per line is fairly easy. You pick a goody body copy font, you adjust the size of the font and width of the container to be about right.

But what do you do in a world of flexy widths?

(more…)

Email Domain Datalist Helper

What if someone signs up for your web app and they type in their email address as susan_smith@gmaoil.com? They don't notice, they never get their confirmation email, they never can log in again, the "forgot password" feature doesn't work, and there is a lot of frustration and finger pointing.

Can't we help with that?

(more…)

Conditional Media Query Mixins

Sass makes working with media queries pretty excellent. You can nest them right within other blocks of CSS, which puts the properties and values you are changing right next to each other. That creates an obvious connection between them, which is a much nicer authoring experience than trying to maintain those changes separated by tons of other code or in a different file. We've covered this before. It was new in Sass 3.2.

.column-1-3 {
  width: 33.3333%;
  @media (max-width: 600px) {
    width: 100%;
  }
}

But since we're likely to do that over and over again, we should abstract that media query away like we would any other variable.

$bp-babybear: "(max-width: 600px)";

.column-1-3 {
  width: 33.33%;
  @media #{$bp-babybear} {
    width: 100%;
  }
}

It's more common to see a @mixin be used though, in conjunction with Sass @content blocks. We covered this in the article Naming Media Queries:

@mixin bp($point) {
  @if $point == papa-bear {
    @media (max-width: 1600px) { @content; }
  }
  @else if $point == mama-bear {
    @media (max-width: 1250px) { @content; }
  }
  @else if $point == baby-bear {
    @media (max-width: 600px)  { @content; }
  }
}

Which you use like this:

.sidebar {
  width: 33.33%;
  @include bp(baby-bear) {
    width: 100%;
  }
}

And there is no reason you can't do both, abstracting away the media queries into variables, if you prefer the look of that:

@mixin bp($point) {
  
  $bp-babybear: "(max-width: 600px)";
  $bp-mamabear: "(max-width: 1250px)";
  $bp-papabear: "(max-width: 1600px)";

  @if $point == papa-bear {
    @media #{$bp-papabear} { @content; }
  }
  @else if $point == mama-bear {
    @media #{$bp-mamabear} { @content; }
  }
  @else if $point == baby-bear {
    @media #{$bp-babybear}  { @content; }
  }

}

Which has the exact same usage.

As an aside, I like "bp" as a name, because it's something you have to type over and over and it's short and sweet.

At a glance, it seems like the @mixin approach has limited value. Just using a variable is less verbose and makes just as much sense. However with the @mixin, we are granted additional powers!

Perhaps we want to create a version of a stylesheet which contains no media queries at all. This is absolutely reasonable in some circumstances. Perhaps we want to create an IE 8 and down stylesheet. Nicolas Gallagher toyed with using Sass for this years ago, but this is slightly different. IE 8 and down do not natively support media queries so perhaps we decide we're going to serve them a stripped down stylesheet which does not include them at all. Old browsers like that are slower anyway, so instead of punishing them with additional code they can't use, we're helping them by serving them less. Sort of the Universal IE 6 Stylesheet idea.

We can use a combination of conditional comments to do that:

<!--[if !IE 8]><!-->
  <link rel="stylesheet" href="style.css">
<!--<![endif]-->

<!--[if gte IE 9]>
  <link rel="stylesheet" href="style.css">
<![endif]-->

<!--[if lte IE 8]>
  <link rel="stylesheet" href="style-NoMQs.css">
<![endif]-->

Another reasonable and real-world reason to serve a stylesheet stripped of media queries is if you have some pages of your site that use responsive design and some pages of your site that have a mobile-specific version. I think that's reasonable. The pages that have a mobile-specific version don't really need those media queries in them.

So how do you create both a style.css and a style-NoMQs.css from the same source Sass? We use the power of our @mixin.

We use a logic condition within the bp @mixin which will either continue and output the media query, or output nothing.

$MQs: true;

@mixin bp($point) {
  @if ($MQs) {
    $bp-babybear: "(max-width: 600px)";
    $bp-mamabear: "(max-width: 1250px)";
    $bp-papabear: "(max-width: 1600px)";
  
    @if $point == papa-bear {
      @media #{$bp-papabear} { @content; }
    }
    @else if $point == mama-bear {
      @media #{$bp-mamabear} { @content; }
    }
    @else if $point == baby-bear {
      @media #{$bp-babybear}  { @content; }
    }
  }
}

You wouldn't declare that variable right outside the @mixin though. You would declare it from your "master" file that @imports all the partials. So perhaps your style.scss file is:

$MQs: true;

@import "variables";
@import "colors";
@import "global";
/* etc. */

And you create the "No Media Queries" version (style-NoMQs.css) by creating a style-NoMQs.scss:

$MQs: false;

@import "variables";
@import "colors";
@import "global";
/* etc. */

Just change that variable to false, and the output CSS will contain no media queries at all.

Big props to Cat Farman who wrote about this very idea in her Cognition article Fall Back to the Cascade, with the slight variation of passing the support variable to the @mixin itself. (Is that safer?)

And as a final aside, I know many folks who don't like how Sass outputs repetitive media queries in the final output, only "bubbling out" the media query as far as the bottom of the nesting. That's necessary to honor the source-order-specificity of the selector (as I understand it). I've personally never worried about it since, since I always serve assets with GZip enabled, and GZip eats repetitive text for breakfast, it doesn't change the file size that much. Not to mention browsers have no problem zooming through and applying those rules. However if you still don't like that (or I'm wrong), there is a Grunt plugin for that.

Other Approaches

Animating DOM transitions

Say you add some new element to the page and it pushes things around. That can happen instantly, but it helps your brain understand what just happened if the elements that were pushed away animate to their new position. Enter Alex MacCaw and his new magicMove jQuery plugin:

The library works by appending a separate and hidden clone of the element you’re transitioning to the page. Any DOM manipulation you do is actually manipulating that clone. Then, when you’re finished, the library looks at the difference between the element’s current position, and the clone’s position, and animates between them (using CSS transitions).

Objects in Space

I'm a big fan of the front end architecture thinking here by Andrew Colclough.

I want my approach to solving this user problem to be re-usable, independent, and adaptable to different use cases.

Flat UI and Forms

Jessica Enders:

The problem is that in the push for simplicity, flat UIs may have gone too far.

Important stuff about the actual usability of forms while the "flat design" trend is perhaps at its peak. I highly suspect that as time goes on we'll start seeing traditional affordances seep back into designs, like buttons that look like buttons and form fields that look (as Jessica aptly puts it) "hollow".

CSS-Tricks Chronicle XV

Life's been pretty good lately! I've just signed a land contract with my previous landlord to buy the house I'm living in, in Milwaukee. I quite like Milwaukee and the house, so I'm excited about that. Feels a bit grown-uppy.


Last month I took a trip to Scotland with some friends which was great, in part because it's the only non-tech trip I've taken in some time.


I'm significantly healthier than I was 3-4 months ago. I'm down about 40lbs. I have quite a ways to go to be truly healthy, but I'm doing all the right stuff including a lot of walking, biking, weight training, and eating better and drinking less. I've already booked another stay at the health resort thing that helped me kick it off, so I can really keep it going.


I spoke at my first An Event Apart event in Austin earlier this month. That was cool. I'm doing another in San Francisco in December, but if you don't already have a ticket I'm afraid it's sold out.

This Sunday I leave for CSS Dev Conf which is exciting and obviously right up my alley for a conference focus. I'm polishing my slides right now.


I got to be a guest on some podcasts since I've last done one of these Chronicles. Pixel Recess and Dorm Room Tycoon. The Dorm Room Tycoon one wasn't published, so not sure if that just didn't work out or what, but it's a good show worth checking out.


Speaking of podcasts, ShopTalk took a few weeks off while Dave and his wife tended to their brand new baby Otis. We're now back with what we're calling Season 3 in which we'll have shows every week through at least the holidays.


Most of my time, as always, is dedicated to CodePen. Since the last Chronicle, we've released several major features and countless little features and improvements. Among the biggest features: Customizeable Embeds, the Mobile Editor, and much better Comment Notifications.

We recently got the team together in Bend, Oregon (where Tim lives) for some co-working which was fun and productive. We're doing another little mini-sprint together in December in Palo Alto (where Alex lives).


The year is still going for The Pastry Box Project where I write monthly. Several posts since last time including article about my internal struggle with spammers, my one bit of advice regarding "success", and a fake story about mustard.

New T-Shirts! New Store!

Hey hey everybody, I made some new shirts! I wanted some T-Shirts that were more of just the straight CSS-Tricks logo type. So I had some made up. While I was at it, I moved the entire store system (as you do).

(more…)

Thoughts on GoDaddy buying MediaTemple

Today it was announced that GoDaddy purchased MediaTemple. I've been a long time user of both of them. I thought I'd share my thoughts. Full disclosure: this site is on a free server they give me. I pay for other MediaTemple services. I also use their affiliate program but there are no affiliate links in this article.

(more…)

Cargo cult analytics

There is a lot to quote in this great article by Stijn Debrouwere:

There’s nothing like a dashboard full of data and graphs and trend lines to make us feel like grown ups.

... metrics only make sense when you’re going to do something with them.

I’ve never seen a news organization that has a workflow that would allow them to routinely respond to their readers’ behavior right now.

1) Have an idea where, depending on data, you’ll do A, B, or C. 2) THEN look at data. 3) Then do A, B, or C.

Introversion and UX

Angela Craven and SuAnne Hall with thoughts, interviews, and research into introversion can be an asset to the UX field. Like the majority of folks in the world of computers, I am introverted and a fairly full-tilt one at that. My own thoughts. And a funny reminder not to be too obnoxious about it.

Animated Media Queries

If you apply a transition on an element for a particular supported property, and that property ever changes, it will use that transition. If a class name on that element changes and the new class changes that property, it will transition (assuming what that class does isn't remove the transition). If JavaScript literally changes the that style property, it will transition.

Likewise, if a new media query takes affect, and that media query has something in it that changes that property on that element, it will transition. (more…)

Creating a “Meet The Team” Page in WordPress

The following is a guest post by Kevin Leary. I was pretty stoked to get this guest post submission from Kevin because it's my favorite kind of tutorial: practical and detailed.

Almost every custom theme I develop with WordPress requires a Management Team or Meet the Team page. If I had to guess, I'd say that I've built just around 50 different setups. It occurred to me that their must be many other WordPress developers out there creating similar systems as well. For this reason, I'll share the approach I typically use to build and manage a "Meet The Team" page in WordPress.

(more…)

Conical Gradients in CSS

The following is a guest post by Shankar Cabus. Shankar made a really rad color wheel on CodePen and showed it to me. I thought it was an image underneath, because gradients like this aren't something CSS can natively do. Or so I thought. Shankar found a way to do it with newfangled tech.

When I create filters, shadows, transformations or gradient backgrounds in CSS, it feels amazing. Who would have thought CSS would come this far. No need to use images for any of that stuff. I can almost hear the browser telling me "don't worry, I do it for you."

Despite all this evolution, CSS still has limitations. For instance, background gradients can only be created in linear or radial styles, but not a conical shape.

In 2011, Lea Verou started a thread about implementing a native CSS conical gradient, creating a draft specification which has already been introduced to W3C's official draft. However, we still have to wait for the W3C to formalize the feature and for the browsers to implement it, which might still take quite some time. In the meantime, I will show you how to simulate a conical gradient using CSS3 only.

Example of a conical gradient.

Beautiful, right? Let's look at the code!

The Beginning

To reduce code duplication, I'm using Sass. One of the most interesting features of CSS preprocessors is the @mixin. A @mixin is a blend of function and include which, when called, returns its contents.

@mixin circle($size) {
  content: "";
  position: absolute;
  border-radius: 50%;
  width: $size;
  height: $size;
  left: calc(50% - #{$size/2});
  top: calc(50% - #{$size/2});
}

This @mixin is only used to set properties of shape and placement, creating a circle of absolute position and centered horizontally and vertically in relation to its parent.

The Magic!

By combining a @mixin circle with the clip property, we can get a semi-circle. Let's start by creating a full circle by placing two semi-circles (with different colors) together. Can you imagine what is going to happen if we rotate one of the semi-circles? Magic!

$wheel: 15em;
.color {
  @include circle($wheel);
  background: red;
  clip: rect(0, $wheel, $wheel, #{$wheel/2});
  &:after {
    @include circle($wheel);
    background: blue;
    clip: rect(0, #{$wheel/2}, $wheel, 0);
    transform: rotate(45deg);
  }
}

The clip: rect (top, right, bottom, left) property restricts the visible area to a rectangular element, which causes only half of the red circle to be seen in the example above. The same principle is applied to the blue circle, the .color:after element. At this point we would have a full circle which is half red and half blue. However, the transform property causes the blue circle's visible area to invade the red circle's. See example.

Semi-circles with clip property

The Colorful Umbrella

Colorful umbrella

We already know how to perform this magic trick. Let's create a 12 color umbrella:

<div class="wheel">
  <ul class="umbrella">
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
  </ul>
</div>

Since we want to create a full circle by combining semi-circles, from the seventh item (first item in the second half), we must reverse the clip:

.color, .color:nth-child(n+7):after {
  clip: rect(0, $wheel, $wheel, #{$wheel/2});
}
.color:after, .color:nth-child(n+7) {
  @include circle($wheel);
  clip: rect(0, #{$wheel/2}, $wheel, 0);
}

From the seventh item, the .color becomes a semi-circle with the left half of the circle and the .color:after elements pass to the right half of the circle.

We are almost done!! We need to change the colors and the angle of each element. Again, let's abuse the power of Sass to generate 26193^42 lines of code in just over 10 ;)

$colors: (#9ED110, #50B517, #179067, #476EAF, #9f49ac, #CC42A2, #FF3BA7, #FF5800, #FF8100, #FEAC00, #FFCC00, #EDE604);
@for $i from 0 to length($colors) {
  .color:nth-child(#{1+$i}):after {
    background-color: nth($colors, $i+1);
    @if $i < 6 {
      transform: rotate(#{30*(1+$i)}deg);
      z-index: #{length($colors)-$i};
    } @else {
      transform: rotate(#{-30+(30*(1+$i))}deg);
    }
  }
}

First, we define the $colors array with the "12 colors of the rainbow" and then iterate over the list creating .color:nth-child(n):after selector with the background-color, rotate and z-index properties.

The rotate property has some important points. Its angle is defined according to the number of colors in the circle. In our case, there are 12 colors, so 360/12 = 30 is the rotation of each color. But from the seventh item on, the other half of the circle starts, remember? Thus, the process we just described stops at the seventh item. We will then start the very same process again, but this time, the rotation will take place on another direction.. That's why there is an @else with rotate(#{-30+(30*($i+1))}deg) which subtracts 30 degrees from the elements of the second half of the circle.

If you are a good observer (and understood everything so far), you should have noticed that our our umbrella is actually a fan! Bazinga! So for the last color of the first half of the circle does not get on top of other colors, we need to reverse the index of these elements. For example, the z-index (6) = 1 and z-index (1) = 6.

A Little More Magic

Finally, we need to ease the transition between colors, after all, we don't want an umbrella-range-rainbow, we want a conical gradient!

.umbrella {
  -webkit-filter: blur(1.7em);
}

.wheel {
  overflow: hidden;
  box-shadow: inset 0 0 0 3em rgba(0, 0, 0, 0.3);
}

The blur filter is responsible for mixing the colors. But, by applying the blur, the colors strain the limits of the circle. That's why the overflow: hidden property was also added to the .wheel element. The inner box-shadow is used to darken the edges that were "washed out". This is the end result:

See the Pen Conical gradient in pure CSS by Shankar Cabus (@shankarcabus) on CodePen

Demo

The conical gradient can be used in different ways to create different effects. But one of the most interesting applications is the Color Picker, as in the example below:

See the Pen Color Picker in Pure CSS by Shankar Cabus (@shankarcabus) on CodePen

Other Demos

Editor's note: I've seen many other approaches to this over time. I'll start dropping them here as a reference.

See the Pen css conical gradient by Kai Waddington (@waddington) on CodePen.

Another demo by Michael Wehner.

Just Use [insert CMS here]! Or, Why I Still Love WordPress

I somewhat regularly ask questions about WordPress stuff on Twitter. Usually when I don't know how to do something or I'm seeing behavior that I didn't expect. I did write a book about WordPress at one time, but even when I was immersed in that, I wasn't an expert on every aspect of WordPress. Especially the deep developer-y stuff. When I ask a question, I'll always get at least a few responses like:

(more…)

Focus transition

More cleverness by Nikita Vasilyev. The blue glow outline that surrounds focusable elements when they are in their :focus state "flies" (you have to see it) to the next focusable element. So when you tab around, it is very clear where the focus has moved to.

I think it's a light enough effect that the cognitive gains are worth the animation. No feedback yet from anyone visually impaired. It would be great to know if this is helpful to them.

Targeting Menu Elements with Submenus in a Navigation Bar

The following is a guest post by Ray Messina. Ray was interested in sharing this technique as a way to pay forward things he's learned from this site in the past, which is awesome. You might be aware of the jQuery .has method, which allows you to select an element if it has any of another selector as a descendant. There is sadly no such selector in CSS yet. But if you know a little something about the HTML structure, you can use a combination of positional selectors to mimic it. Ray will explain.

(more…)

CSS Property Usage > Popularity

And the most-used CSS property is... (guess before you click through).

There are some funny ones at the bottom. Hopeful ones like kerning and not-enough-coffee ones like text-underline.

A Complete Guide to the Table Element

The <table></table> element in HTML is used for displaying tabular data. You can think of it as a way to describe and display data that would make sense in spreadsheet software. Essentially: columns and rows. In this article we're going to look at how to use them, when to use them, and everything else you need to know.

(more…)

icon-closeicon-emailicon-linkicon-menuicon-searchicon-tag