Intermediate Articles

Case Study: jQuery Fixer Upper

Recently in the CSS-Tricks Forums, user named Waffle posted the following bit of jQuery JavaScript:

$(function(){

	$('.ContactArea').hide();
                
	$('.Portfolio').hide();
                
	$('.WebDesign').hide();

	$('.AboutCoadin').hide();

	$('li.Contact').click(function(){
		$(".ContactArea").slideToggle();
	});

	$('li.PortfolioBtn').click(function(){
		$(".Portfolio").slideToggle();
	});

	$('li.WebDesignBtn').click(function(){
		$(".WebDesign").slideToggle();
	});

	$('li.AboutBtn').click(function(){
		$(".AboutCoadin").slideToggle();
	});
                        
});

This user's actual question was how they can extend their code to add functionality to scroll the page down to the areas as they expand. But in looking at code like this with a slightly more experienced eye, there are things that stick out as things that we can likely improve upon. Since I bet there are some of you folks that are at Waffle's level and writing code like this, I thought we could use this as a case study to learn from.

It works, but...

To start with, Waffle's code isn't broken, it works fine and because of it's simple nature the improvements that we'll end up making probably won't even make noticeable speed improvements. However, the improvement we make should make the code more readable, more efficient, more extensible, and improve other related things. Also, understanding the improvements we make will make us better coders in the future when the stakes are higher.

Do we need a DOM ready statement?

The first line of code is this:

$(function(){

...which is jQuery shorthand for "When the DOM is ready to manipulated, run this function..." This is a safety net so that, for example, selectors aren't run on HTML that isn't parsed yet, leaving us wondering WTF. It also doesn't wait until the page has fully loaded, which would make our script appear sluggish.

But the thing is, we should be running scripts like this at the bottom of our pages (before the closing </body> tag), so that loading the script doesn't hold up page rendering. If we load scripts properly at the bottom of the page, a DOM ready statement isn't needed, as the browser has dealt with all that HTML before it has even started reading the script.

Multiple Selectors, One jQuery Object

The next lines of code are:

$('.ContactArea').hide();             
$('.Portfolio').hide();     
$('.WebDesign').hide();
$('.AboutCoadin').hide();

Creating four separate jQuery objects here is unnecessary, as you can use multiple selectors in one. This does the same thing:

$(".ContactArea, .Portfolio, .WebDesign, .AboutCoadin").hide();

Just like a CSS selector. However, you might actually want four separate jQuery objects, so that you can refer to them later without needing to create them new. In that case, set variables:

var contactArea = $('.ContactArea').hide(),
    portfolio   = $('.Portfolio').hide(),
    webDesign   = $('.WebDesign').hide(),
    about       = $('.AboutCoadin').hide();

You might also consider adding a class name to the HTML like "initial-hide" and applying it to all elements you wish to hide at time of page load and selecting by that, but that may walk on the wrong side of the semantics line.

ID's

It's hard to say without seeing the real website, but I have a feeling that these areas like "contact area" and "portfolio" are totally unique areas on the page, not things that are repeated more than once. Totally unique areas are ideal for using ID's (as opposed to classes). The benefit here being that ID selectors are faster.

$("#ContactArea") // is faster than
$(".ContactArea")

The other important things about ID's is that they are natural jump-links, which work regardless of JavaScript being enabled:

<!-- This link will jump down the page ... -->
<a href="#ContactArea">Contact</a>

<!-- ... to ensure this element is visible -->
<section id="ContactArea"></section>

You may not actually want the page to jump down, but you can stop that with JavaScript by preventing default behavior. Without JavaScript, you definitely want same-page navigation to be jump links.

Select the appropriate element

The next bit of code has four repetitive bits:

$('li.Contact').click(function(){
	$(".ContactArea").slideToggle();
});

$('li.PortfolioBtn').click(function(){
	$(".Portfolio").slideToggle();
});

$('li.WebDesignBtn').click(function(){
	$(".WebDesign").slideToggle();
});

$('li.AboutBtn').click(function(){
	$(".AboutCoadin").slideToggle();
});

The first thing to discuss there is the actual element being selected. Presumably, the markup is something like this:

<nav>
  <ul>
     <li class="ContactArea"><a href="#">Contact</a></li>
     <li class="PortfolioBtn"><a href="#">Contact</a></li>
     <li class="WebDesignBtn"><a href="#">Contact</a></li>
     <li class="AboutBtn"><a href="#">Contact</a></li>
  </ul>
</nav>

The jQuery code is selecting the list items by their class names. These are my issues with that:

  1. They don't all use the "Btn" convention. If you stick with classes like this, you might as well make it standard. Not sticking to it in this tight of quarters would be symptomatic of other, larger inconsistencies.
  2. You don't need the classes for CSS to style them uniquely. You can use :nth-child or :nth-of-type. Unless you need to support super old browsers, in which case, you are using jQuery anyway and could feign support with that.
  3. Because you don't need them for styling, I'd say you don't really need them at all.

Assuming the markup can be changed to use ID's instead of classes, the HTML could be rewritten like this:

<nav>
  <ul>
     <li><a href="#ContactArea">Contact</a></li>
     <li><a href="#Portfolio">Portfolio</a></li>
     <li><a href="#WebDesign">Web Design</a></li>
     <li><a href="#AboutCoadin">About</a></li>
  </ul>
</nav>

This is a more semantic representation of navigation. No unneccesary classes and anchor links that are same-page links to the appropriate content.

Don't Repeat Yourself

Which is commonly referred to as "DRY." The four statements that do all that selecting and slideToggling are very repetitive. We can improve upon that with our new and improved HTML structure.

The href attribute for those anchor links in the navigation are like "#Contact", which is exactly what we need as a selector string to find that element. Super convenient! Let's yank that href from the link and use it as a selector, that way one single click handler can handle all four of our links:

$("nav a").click(function(e){
  e.preventDefault();
  $($(this).attr("href")).slideToggle();
});

Final Code

Our final code ends up being much more succinct:

$("#ContactArea, #WebDesign, #Portfolio, #AboutCoadin").hide();

$("nav a").click(function(e){
  e.preventDefault();
  $($(this).attr("href")).slideToggle();
});

View Demo

To actually answer Waffle's question

The posed question was actually "I also want the page to scroll to those divs when those buttons are pressed" To which I would say, are you sure? That seems like a weird combination of animated activity. Smooth scrolling same-page links are actually a little more complicated than you might think, but I have some great copy-and-pasteable code for them here. The problem is that it won't quite work in this scenario, because at the time the link is clicked the element to scroll to is actually hidden. It's not until the slideToggle is done where the element is unhidden and at it's final size. You'd have to delay the page scroll until the callback function for that. Doable, but janky.

Did I do OK?

One of my favorite parts about publishing blog posts on this site is that people really take the time to read it and offer quality suggestions. If you have some even better ways at handling the things I suggested above, I'd love to hear it!

Styling Texty Inputs Only

Let's say you want fancy styling your your text inputs:

So you go and style those inputs:

input {
    border: 5px solid white; 
    -webkit-box-shadow: 
      inset 0 0 8px  rgba(0,0,0,0.1),
            0 0 16px rgba(0,0,0,0.1); 
    -moz-box-shadow: 
      inset 0 0 8px  rgba(0,0,0,0.1),
            0 0 16px rgba(0,0,0,0.1); 
    box-shadow: 
      inset 0 0 8px  rgba(0,0,0,0.1),
            0 0 16px rgba(0,0,0,0.1); 
    padding: 15px;
    background: rgba(255,255,255,0.5);
    margin: 0 0 10px 0;
}

But then you add a few more inputs, a file input and the submit button, and you get sad face because you didn't want those styles to affect those elements.

So then you are like no-prob-bob, I'll just make sure to only style text inputs!

input[type=text] {
   /* Awesome styling */
}

But then you realize as you build out your form, you want to make use of the new HTML5 input types. Those new input types mean better accessibility, better mobile support, and enhanced desktop browser experiences. There is type=email, type=url, type=tel, type=number, type=color, and a bunch more! This is going to get cumbersome...

input[type=text],
input[type=url],
input[type=tel],
input[type=number],
input[type=color],
input[type=email], {
   /* And that ain't all of them... */
}

What are we to do? Well my favorite way would be to harness CSS3 and the :not() selector. So instead of including all the new types, we exclude the ones we don't want styled.

input:not([type=submit]):not([type=file]) {
   /* omg so much cleaner */
}

Now you're back to square one (default user agent stylesheet) on those other inputs. Don't be afraid to use browser default form controls, people know them and are used to them.

But hold on there hotpants. IE doesn't support that :not() selector until version 9, which isn't even really out yet. Yes indeed, and that sucks. However, if you want to polyfix that sucka you could do so with a quick copy-and-paste job.

<!--[if lt IE 9]>
<script src="//ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js"></script>
<![endif]-->

That is from this project which:

Upgrade[s] MSIE5.5-8 to be compatible with modern browsers.

Not interested in that? Well you could always just list out all the attribute selectors like I listed above, which will get you back to IE7 support. Or, you could go back to just adding class names onto every single input and selecting by that which should take you back to the beginning of the internet.

Keep Margins Out of Link Lists

When building a menu or other list of links, it's generally a good practice to use display: block; or display: inline-block; so that you can increase the size of the link target. The simple truth: bigger link targets are easier for people to click and lead to better user experience.

(more…)

Perfect Full Page Background Image

This post was originally published on August 21, 2009 and is now being being republished as it has been entirely revised. Both original methods are removed and now replaced by four new methods.

The goal here is a background image on a website that covers the entire browser window at all times. Let's put some specifics on it:

  • Fills entire page with image, no white space
  • Scales image as needed
  • Retains image proportions (aspect ratio)
  • Image is centered on page
  • Does not cause scrollbars
  • As cross-browser compatible as possible
  • Isn't some fancy shenanigans like Flash

Image above credited to this site.

Awesome, Easy, Progressive CSS3 Way

We can do this purely through CSS thanks to the background-size property now in CSS3. We'll use the html element (better than body as it's always at least the height of the browser window). We set a fixed and centered background on it, then adjust it's size using background-size set to the cover keyword.

html { 
  background: url(images/bg.jpg) no-repeat center center fixed; 
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
}

Works in:

  • Safari 3+
  • Chrome Whatever+
  • IE 9+
  • Opera 10+ (Opera 9.5 supported background-size but not the keywords)
  • Firefox 3.6+ (Firefox 4 supports non-vendor prefixed version)

View Demo

Update: Thanks to Goltzman in the comments for pointing out an Adobe Developer Connection article which features some code to make IE do cover backgrounds as well:

filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='.myBackground.jpg', sizingMethod='scale');
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='myBackground.jpg', sizingMethod='scale')";

But careful, reader Pierre Orsander said they tried this and had some problems with links on the page going dead.

Update: Matt Litherland writes in to say that anyone trying to use the above IE filters and having problems with scrollbars or dead links or whatever else (like Pierre above) should try NOT using them on the html or body element. But instead a fixed position div with 100% width and height.

CSS-Only Technique #1

Big thanks, as usual, to Doug Neiner for this alternate version. Here we use an inline <img> element, which will be able to resize in any browser. We set a min-height which keeps it filling the browser window vertically, and set a 100% width which keeps it filling horizontally. We also set a min-width of the width of the image so that the image never gets smaller than it actually is.

The especially clever bit is using a media query to check if the browser window is smaller than the image, and using a combo percentage-left and negative left margin to keep it centered regardless.

Here is the CSS:

img.bg {
  /* Set rules to fill background */
  min-height: 100%;
  min-width: 1024px;
	
  /* Set up proportionate scaling */
  width: 100%;
  height: auto;
	
  /* Set up positioning */
  position: fixed;
  top: 0;
  left: 0;
}

@media screen and (max-width: 1024px) { /* Specific to this particular image */
  img.bg {
    left: 50%;
    margin-left: -512px;   /* 50% */
  }
}

Works in:

  • Any version of good browsers: Safari / Chrome / Opera / Firefox
  • IE 6: Borked - but probably fixable if you use some kind of fixed positioning shim
  • IE 7/8: Mostly works, doesn't center at small sizes but fills screen fine
  • IE 9: Works

View Demo

CSS-Only Technique #2

One rather simple way to handle this is to put an inline image on the page, fixed position it to the upper left, and give it a min-width and min-height of 100%, preserving it's aspect ratio.

<img src="images/bg.jpg" id="bg" alt="">
#bg {
  position: fixed; 
  top: 0; 
  left: 0; 
	
  /* Preserve aspet ratio */
  min-width: 100%;
  min-height: 100%;
}

However, this doesn't center the image and that's a pretty common desire here... So, we can fix that by wrapping the image in a div. That div we'll make twice as big as the browser window. Then the image will be placed, still preserving it's aspect ratio and covering the visible browser window, and the dead center of that.

<div id="bg">
  <img src="images/bg.jpg" alt="">
</div>
#bg {
  position: fixed; 
  top: -50%; 
  left: -50%; 
  width: 200%; 
  height: 200%;
}
#bg img {
  position: absolute; 
  top: 0; 
  left: 0; 
  right: 0; 
  bottom: 0; 
  margin: auto; 
  min-width: 50%;
  min-height: 50%;
}

Credit to Corey Worrell for the concept on this one.

Works in:

  • Safari / Chrome / Firefox (didn't test very far back, but recent versions are fine)
  • IE 8+
  • Opera (any version) and IE both fail in the same way (wrongly positioned, not sure why)
  • Peter VanWylen wrote in to say that if you add the image via JavaScript, the img needs to have width: auto; and height: auto; to work in IE 8, 9, or 10.

View Demo

jQuery Method

This whole idea becomes a lot easier (from a CSS perspective) if we know if the aspect ratio of the image (inline <img> we intend to use as a background) is larger or smaller than the current aspect ratio of the browser window. If it is lower, than we can set only the width to 100% on the image and know it will fill both height and width. If it is higher, we can set only the height to 100% and know that it will fill both the height and width.

We have access to this information through JavaScript. As usual around here, I like to lean on jQuery.

<img src="images/bg.jpg" id="bg" alt="">
#bg { position: fixed; top: 0; left: 0; }
.bgwidth { width: 100%; }
.bgheight { height: 100%; }
$(window).load(function() {    

	var theWindow        = $(window),
	    $bg              = $("#bg"),
	    aspectRatio      = $bg.width() / $bg.height();
	    			    		
	function resizeBg() {
		
		if ( (theWindow.width() / theWindow.height()) < aspectRatio ) {
		    $bg
		    	.removeClass()
		    	.addClass('bgheight');
		} else {
		    $bg
		    	.removeClass()
		    	.addClass('bgwidth');
		}
					
	}
	                   			
	theWindow.resize(resizeBg).trigger("resize");

});

This doesn't account for centering, but you could definitely alter this to do that. Credits to Koen Haarbosch for the concept behind this idea.

Works in:

  • IE7+ (could probably get in IE6 with a fixed position shim)
  • Most any other desktop browser

View Demo

Update (June 2012): Reader Craig Manley writes in with a technique to load an appropriately sized background image according to screen. As in, don't load some huge 1900px wide background image for an iPhone.

First, you'd make images like 1024.jpg, 1280.jpg, 1366.jpg, etc. Then instead of loading an img, you'd load a shim.

<img id="bg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="" style="position: fixed; left: 0; top: 0" />

If you don't like the gif shim (personally I think it's OK because it's not "content" it's a background) you could load up one of the real images instead. This code will account for that.

Then you test the screen width and set the src of the image based on it. The code below does it on resize, which you may or may not want. You could just run the code once if you wanted.

(function() {

var win = $(window);

win.resize(function() {
    
    var win_w = win.width(),
        win_h = win.height(),
        $bg    = $("#bg");

    // Load narrowest background image based on 
    // viewport width, but never load anything narrower 
    // that what's already loaded if anything.
    var available = [
      1024, 1280, 1366,
      1400, 1680, 1920,
      2560, 3840, 4860
    ];

    var current = $bg.attr('src').match(/([0-9]+)/) ? RegExp.$1 : null;
    
    if (!current || ((current < win_w) && (current < available[available.length - 1]))) {
      
      var chosen = available[available.length - 1];
      
      for (var i=0; i<available.length; i++) {
        if (available[i] >= win_w) {
          chosen = available[i];
          break;
        }
      }
      
      // Set the new image
      $bg.attr('src', '/img/bg/' + chosen + '.jpg');
      
      // for testing...
      // console.log('Chosen background: ' + chosen);
      
    }

    // Determine whether width or height should be 100%
    if ((win_w / win_h) < ($bg.width() / $bg.height())) {
      $bg.css({height: '100%', width: 'auto'});
    } else {
      $bg.css({width: '100%', height: 'auto'});
    }
    
  }).resize();
  
})(jQuery);

Note that screen width isn't the only possible good information to have when choosing an image size. See this article.

Enjoy

If you use this, please feel free to leave what technique you used and if you altered it in any way in the comments below. Always cool to see techniques "in the wild."

Download Files

Just for posterity's sake, there is another example in here called table.php which uses an old technique that used to be a part of this article. It had some cleverness, but wasn't quite as good as either CSS technique now presented above.

Other Resources

  • jQuery plugin: Vegas, by Jay Salvat

Transparent Borders with background-clip

Have you ever seen an element on a page with transparent borders? I think Facebook originally popularized it giving birth to lightbox plugins like Facebox. I don't think Facebook sports the look anymore, but it's still rather neat.

You might think it would be as simple as this:

#lightbox {
   background: white;
   border: 20px solid rgba(0, 0, 0, 0.3);
}

However, setting a transparent border on an element will reveal the elements own background underneath the border.

In the screenshot above, the borders use RGBa to be transparent, but they appear solid gray because they are only revealing the solid white background of itself below.

Fortunately there is a CSS3 property to save us! It's called background-clip and it's used specifically to specify which portion of the box model should be utilized to display the background. It does what it sounds like it does, it cuts off the background at the specified portion of the box. There are three values it can have, and vendor prefixes do get involved. Here are the three settings it could have. You wouldn't use them all at once, this is for convenience of displaying only:

#lightbox {

  -moz-background-clip: border;     /* Firefox 3.6 */
  -webkit-background-clip: border;  /* Safari 4? Chrome 6? */
  background-clip: border-box;      /* Firefox 4, Safari 5, Opera 10, IE 9 */
				
  -moz-background-clip: padding;     /* Firefox 3.6 */
  -webkit-background-clip: padding;  /* Safari 4? Chrome 6? */
  background-clip: padding-box;      /* Firefox 4, Safari 5, Opera 10, IE 9 */
				
  -moz-background-clip: content;     /* Firefox 3.6 */
  -webkit-background-clip: content;  /* Safari 4? Chrome 6? */
  background-clip: content-box;      /* Firefox 4, Safari 5, Opera 10, IE 9 */
				
}

Here are the schematics:

So I'm sure you see where I'm going here... if we set the background-clip to the padding-box, the white background will end before the border and the transparency will lay over other content acheiving the look we are going for!


View Demo

Related: background-origin

In our lightbox example, it's most likely that the background is a solid color. In that case, background-origin is rather irrelevant, as nobody will ever be able to tell where the color "started" from. However, if the background of the element is an image, it can be quite important where the origin point of the background starts.

This is related to background-clip, because if the background-clip is the padding-box but the background-origin is left at the default border-box, some of the background-image will be cut off, which may or not be desireable.

Here is the schematic:

And a visual example:

Browser Compatibility

Works in: Safari 5, Chrome 7, Firefox 3.6+, Opera 10, IE 9

I only tested these modern browsers and support is good. It may (and likely does) go back a bit further in the non-IE browsers.

If you'd more complete browser compatibility, you can always go with the double-div method.

<div id="lightbox">
   /* Set transparent background with PNG
       add padding to push inside box inward */

   <div id="lightbox-inside">
      /* Set white background in here */
   </div>

</div>

Another advantage to the double-div method is that you could achieve truly rounded borders. Unfortunately with the background-clip method, the outer border is round but the edge of the background stays straight-cornered.

Too bad we don't have something like background-radius to fix it:

#lightbox
   border-radius: 16px;
   padding: 8px;

   /* NOT REAL */
   background-radius: 8px;
}

Weirdnesses

20px of border was fine, but when I tried 30px, these mini boxes of death showed up in Safari 5.

In Chrome, little diagonal lines were present at any border width up to 20px.

Above 20px border, the corners completely darken.

Without border-radius, darkened corner boxes are always visible.

Thanks

Thanks to Alex Hall for the original idea and help.

Here's a simple demo showing the different values of background-clip as well:

Check out this Pen!

and background-origin:

Check out this Pen!

Adding Stroke to Web Text

Fonts on the web are essentially vector based graphics. That's why you can display them at 12px or 120px and they remain crisp and relatively sharp-edged. Vector means that their shape is determined by points and mathematics to describe the shape, rather than actual pixel data. Because they are vector, it would make sense if we could do things that other vector programs (e.g. Adobe Illustrator) can do with vector text, like draw a stroke around the individual characters. Well, we can! At least in WebKit. Example:

h1 {
   -webkit-text-stroke-width: 1px;
   -webkit-text-stroke-color: black;
}

Or shorthand:

h1 {
   -webkit-text-stroke: 1px black;
}

Right away, I'm sure you are thinking: "Cool, but only WebKit supports, this, so if I set my text color to white and my background is white, the stroke makes it look cool in WebKit but disappears in other browsers!"

WebKit has your back on that one, you can set the text color with another proprietary property, so you're safe for all browsers:

h1 {
   color: black;
   -webkit-text-fill-color: white; /* Will override color (regardless of order) */
   -webkit-text-stroke-width: 1px;
   -webkit-text-stroke-color: black;
}

Shown here with @font-face font Anime Ace 2 by Nate Piekos:

Properly stroked!

Fallback to solid color. Shown here in Firefox

Simulation

We can take this a bit further by not relying on the WebKit proprietary entirely. We can use the text-shadow property (supported in Firefox, Opera, and IE 10 as well) and simulate a stroke. We'll use four shadows, each 1px offset of black with no spread, one each to the top right, top left, bottom left, and bottom right. We'll use remove the WebKit propreitary -webkit-text-fill-color in favor of color since we're cross-browser compatible now. The only holdout would be IE9 and down, which of course you can use IE specific stylesheets to account for.

h1 {
  color: white;
  text-shadow:
   -1px -1px 0 #000,  
    1px -1px 0 #000,
    -1px 1px 0 #000,
     1px 1px 0 #000;
}

This is a stroke using all text-shadow. Pretty close to just as good as a real stroke. The primary issue is that you can only get 1px of stroke this way. Any more, and you see gaps. Any more with WebKit text stroke and there is issues too though, so it's kind of a horse apiece.

Combining

Using both a stroke and a shadow can be a great effect. Let's toss on a WebKit stroke, the all-around text-shadow stroke, as well as a deeper text-shadow stroke.

h1 {
   -webkit-text-stroke: 1px black;
   color: white;
   text-shadow:
       3px 3px 0 #000,
     -1px -1px 0 #000,  
      1px -1px 0 #000,
      -1px 1px 0 #000,
       1px 1px 0 #000;
}

Lookin' good

Alignment

If you are familiar with Adobe Illustrator, you may know that you can align a stroke on the inside of a shape, outside, or centered. That option looks like this in the palette:

From left to right: center, inside, outside

For reasons unbeknownst to me, text in Illustrator can only be set to center stroke alignment as well. Once you expand the text into regular vector paths though, all three options become available. Reminder from Sam Frysteen: add a new stroke in the appearance panel and move it below your text (basically mimics outside stroke alignment).

From top to bottom: inside, centered, outside.

Only outside text stroke alignment looks any good at all to me. It's unfortunate, both for CSS and for Illustrator, that the unchangeable default is centered. The solution is just not to go too crazy with the thickness of your stroke border and things should be OK. Note: the text-shadow-only solution doesn't have this problem, but also is unable to stroke any more than 1px.

If you use a pseudo element, you can stroke the same text behind the original text and kinda fake outside stroke.

What we can't do

There are other things that vector based graphics programs can do with text. You can squish the letter horizontally / stretch them vertically. This type of text treatment is almost universally frowned upon, so no big loss that we can't do that. You can also set type on an irregular line (like around a circle). It certainly would be cool to do this with web text. Perhaps we could set text to follow the border path of its parent element.

p.circular {
  width: 200px;
  height: 200px;
  border-radius: 100px;
  
  /* NOT REAL */
  text-align: border-path;
}

In Illustrator, we can also tell a stroke how to handle sharp corners: rounded, beveled, or mitered. These can have nice effects, are not possible on the web. However, the WebKit handling of corners is pretty nice at its default (whatever it is), and arguably nicer than any of the options in Illustrator.

Fancies

For the record, you can use any type of color value for the color of WebKit stroke (hex, rgba, hsla, keyword). That means transparent strokes if you want them, which indeed to "stack" in that if strokes overlap each other (common) they will be darker.

As far as WebKit keyframe animation, the stroke color will animate but the stroke width will not.

/* Only the color will change, not the width */
@-webkit-keyframes colorchange {
	0% {
		-webkit-text-stroke: 10px red;
	}
	100% {
		-webkit-text-stroke: 20px green;
	}
}

Demo & Download

View Demo   Download Files

Thanks

Thanks to Hendra Susanto and Cory Simmons for sending in ideas and demos.

WebKit HTML5 Search Inputs

One of the new types of inputs in HTML5 is search.

<input type=search name=s/>

It does absolutely nothing in most browsers. It just behaves like a text input. This isn't a problem. The spec doesn't require it to do anything special. WebKit browsers do treat it a bit differently though, primarily with styling.

A search input in WebKit by default has an inset border, rounded corners, and strict typographic control.

(more…)

Textarea Tricks

Oh, <textarea></textarea>'s. How many quirks you posses. Here is a collection of nine things you might want to do related to textareas. Enjoy.

(more…)

Yay for HSLa

Huge sogging longbottoms? High strength low alloy steel? NOPE, we're talking Hue Saturation Lightness (and alpha) and it's a way of declaring color in CSS. It looks like this:

#some-element {
  background-color: hsla(170, 50%, 45%, 1);
}

It is similar to RGBa in that you declare three values determining the color and then a fourth value for its transparency level. You can read more about browser support below, but it's basically any browser that supports rgba supports hsla too.

(more…)

There's a whole bunch of content on CSS-Tricks.

Search for Stuff   •   Browse the Archives

Get the Newsletter ... or get the RSS feed