rowid,title,contents,year,author,author_slug,published,url,topic 110,Shiny Happy Buttons,"Since Mac OS X burst onto our screens, glossy, glassy, shiny buttons have been almost de rigeur, and have essentially, along with reflections and rounded corners, become a cliché of Web 2.0 “design”. But if you can’t beat ‘em you’d better join ‘em. So, in this little contribution to our advent calendar, we’re going to take a plain old boring HTML button, and 2.0 it up the wazoo. But, here’s the catch. We’ll use no images, either in our HTML or our CSS. No sliding doors, no image replacement techniques. Just straight up, CSS, CSS3 and a bit of experimental CSS. And, it will be compatible with pretty much any browser (though with some progressive enhancement for those who keep up with the latest browsers). The HTML We’ll start with our HTML. OK, so it’s not shiny yet – but boy will it ever be. Before styling, that’s going to look like this. Ironically, depending on the operating system and browser you are using, it may well be a shiny button already, but that’s not the point. We want to make it shiny 2.0. Our mission is to make it look something like this If you want to follow along at home keep in mind that depending on which browser you are using you may see fewer of the CSS effects we’ve added to create the button. As of writing, only in Safari are all the effects we’ll apply supported. Taking a look at our finished product, here’s what we’ve done to it: We’ve given the button some padding and a width. We’ve changed the text color, and given the text a drop shadow. We’ve given the button a border. We’ve given the button some rounded corners. We’ve given the button a drop shadow. We’ve given the button a gradient background. and remember, all without using any images. Styling the button So, let’s get to work. First, we’ll add given the element some padding and a width: button { padding: .5em; width: 15em; } Next, we’ll add the text color, and the drop shadow: color: #ffffff; text-shadow: 1px 1px 1px #000; A note on text-shadow If you’ve not seen text-shadows before well, here’s the quick back-story. Text shadow was introduced in CSS2, but only supported in Safari (version 1!) some years later. It was removed from CSS2.1, but returned in CSS3 (in the text module). It’s now supported in Safari, Opera and Firefox (3.1). Internet Explorer has a shadow filter, but the syntax is completely different. So, how do text-shadows work? The three length values specify respectively a horizontal offset, a vertical offset and a blur (the greater the number the more blurred the shadow will be), and finally a color value for the shadow. Rounding the corners Now we’ll add a border, and round the corners of the element: border: solid thin #882d13; -webkit-border-radius: .7em; -moz-border-radius: .7em; border-radius: .7em; Here, we’ve used the same property in three slightly different forms. We add the browser specific prefix for Webkit and Mozilla browsers, because right now, both of these browsers only support border radius as an experimental property. We also add the standard property name, for browsers that do support the property fully in the future. The benefit of the browser specific prefix is that if a browser only partly supports a given property, we can easily avoid using the property with that browser simply by not adding the browser specific prefix. At present, as you might guess, border-radius is supported in Safari and Firefox, but in each the relevant prefix is required. border-radius takes a length value, such as pixels. (It can also take two length values, but that’s for another Christmas.) In this case, as with padding, I’ve used ems, which means that as the user scales the size of text up and down, the radius will scale as well. You can test the difference by making the radius have a value of say 5px, and then zooming up and down the text size. We’re well and truly on the way now. All we need to do is add a shadow to the button, and then a gradient background. In CSS3 there’s the box-shadow property, currently only supported in Safari 3. It’s very similar to text-shadow – you specify a horizontal and vertical offset, a blur value and a color. -webkit-box-shadow: 2px 2px 3px #999; box-shadow: 2px 2px 2px #bbb; Once more, we require the “experimental” -webkit- prefix, as Safari’s support for this property is still considered by its developers to be less than perfect. Gradient Background So, all we have left now is to add our shiny gradient effect. Now of course, people have been doing this kind of thing with images for a long time. But if we can avoid them all the better. Smaller pages, faster downloads, and more scalable designs that adapt better to the user’s font size preference. But how can we add a gradient background without an image? Here we’ll look at the only property that is not as yet part of the CSS standard – Apple’s gradient function for use anywhere you can use images with CSS (in this case backgrounds). In essence, this takes SVG gradients, and makes them available via CSS syntax. Here’s what the property and its value looks like: background-image: -webkit-gradient(linear, left top, left bottom, from(#e9ede8), to(#ce401c),color-stop(0.4, #8c1b0b)); Zooming in on the gradient function, it has this basic form: -webkit-gradient(type, point, point, from(color), to(color),color-stop(where, color)); Which might look complicated, but is less so than at first glance. The name of the function is gradient (and in this case, because it is an experimental property, we use the -webkit- prefix). You might not have seen CSS functions before, but there are others, including the attr() function, used with generated content. A function returns a value that can be used as a property value – here we are using it as a background image. Next we specify the type of the gradient. Here we have a linear gradient, and there are also radial gradients. After that, we specify the start and end points of the gradient – in our case the top and bottom of the element, in a vertical line. We then specify the start and end colors – and finally one stop color, located at 40% of the way down the element. Together, this creates a gradient that smoothly transitions from the start color in the top, vertically to the stop color, then smoothly transitions to the end color. There’s one last thing. What color will the background of our button be if the browser doesn’t support gradients? It will be white (or possibly some default color for buttons). Which may make the text difficult or impossible to read. So, we’ll add a background color as well (see why the validator is always warning you when a color but not a background color is specified for an element?). If we put it all together, here’s what we have: button { width: 15em; padding: .5em; color: #ffffff; text-shadow: 1px 1px 1px #000; border: solid thin #882d13; -webkit-border-radius: .7em; -moz-border-radius: .7em; border-radius: .7em; -webkit-box-shadow: 2px 2px 3px #999; box-shadow: 2px 2px 2px #bbb; background-color: #ce401c; background-image: -webkit-gradient(linear, left top, left bottom, from(#e9ede8), to(#ce401c),color-stop(0.4, #8c1b0b)); } Which looks like this in various browsers: In Safari (3) In Firefox 3.1 (3.0 supports border-radius but not text-shadow) In Opera 10 and of course in Internet Explorer (version 8 shown here) But it looks different in different browsers Yes, it does look different in different browsers, but we all know the answer to the question “do web sites need to look the same in every browser?“. Even if you really think sites should look the same in every browser, hopefully this little tutorial has whet your appetite for what CSS3 and experimental CSS that’s already supported in widely used browsers (and we haven’t even touched on animations and similar effects!). I hope you’ve enjoyed out little CSSMas present, and look forward to seeing your shiny buttons everywhere on the web. Oh, and there’s just a bit of homework – your job is to use the :hover selector, and make a gradient in the hover state.",2008,John Allsopp,johnallsopp,2008-12-18T00:00:00+00:00,https://24ways.org/2008/shiny-happy-buttons/,code 140,Styling hCards with CSS,"There are plenty of places online where you can learn about using the hCard microformat to mark up contact details at your site (there are some resources at the end of the article). But there’s not yet been a lot of focus on using microformats with CSS. So in this installment of 24 ways, we’re going to look at just that – how microformats help make CSS based styling simpler and more logical. Being rich, quite complex structures, hCards provide designers with a sophisticated scaffolding for styling them. A recent example of styling hCards I saw, playing on the business card metaphor, was by Andy Hume, at http://thedredge.org/2005/06/using-hcards-in-your-blog/. While his approach uses fixed width cards, let’s take a look at how we might style a variable width business card style for our hCards. Let’s take a common hCard, which includes address, telephone and email details
Web Directions Conference Pty Ltd
Here’s our CSS for this element .fn { background-image: url(images/topright.png); background-repeat: no-repeat; background-position: top right; padding-top: 2em; font-weight: bold; font-size: 1.1em; } Again, we don’t want it to repeat, but this time, we’ve specified a background position for the image. This will make the background image start from the top, but its right edge will be located at the right edge of the element. I also made the font size a little bigger, and the weight bold, to differentiate it from the rest of the text in the hCard. Here’s the image we are adding as the background to this element. So, putting these two CSS statements together we get We specified a padding-top of 2em to give some space between the content of the fn element and the edge of the fn element. Otherwise the top of the hCard image would be hard against the border. To see this in action, just remove the padding-top: 2em; declaration and preview in a browser. So, with just two statements, we are well under way. We’ve not even had to add any HTML so far. Let’s turn to the bottom of the element, and add the bottom border (well, the background image which will serve as that border). Now, which element are we going to use to add this background image to? OK, here I have to admit to a little, teensie bit of cheating. If you look at the HTML of the hCard, I’ve grouped the email and telephone properties into a div, with a class of telecommunications. This grouping is not strictly requred for our hCard.Phone/Fax: Work: 61 2 9365 5007
Email: info@webdirections.org
Email: info@webdirections.org
Typically, in hCard, the value part of this property isn’t required, and we could get away with info@webdirections.org The form I’ve used, with the span of class value is however, perfectly valid hCard markup (hard allows for multiple email addresses of different types, which is where this typically comes in handy). Why have I gone to all this trouble? Well, when it came to styling the hCard, I realized I needed a block element to attach the background image for the bottom right hand corner to. Typically the last block element in the containing element is the ideal choice (and sometimes it’s possible to take an inline element, for example the link here, and use CSS to make it a block element, and attach it to that, but that really doesn’t work with this design). So, if we are going to use the paragraph which contains the email link, we need a way to select it exclusively, which means that with CSS2 at least, we need a class or id as a hook for our CSS selector (in CSS3 we could use the last-child selector, which selects the last child element of a specified element, but again, as last child is not widely supported, we won’t rely on it here.) So, the least worst thing we could do is take an existing element, and add some reasonably meaningful markup to it. That’s why we gave the paragraph a class of email, and the email address a class of value. Which reminds me a little of a moment in Hamlet The lady doth protest too much, methinks OK, let’s get back to the CSS. We add the bottom right corner image, positioning it in the bottom right of the element, and making sure it doesn’t repeat. We also add some padding to the bottom, to balance out the padding we added to the top of the hCard. p.email { background-image: url(images/bottom-right.png); background-position: right bottom; background-repeat: no-repeat; padding-bottom: 2em; } Which all goes to make our hCard look like this It just remains for us to clean up a little. Let’s start from the top. We’ll float the download image to the right like this .vcard img { float: right; padding-right: 1em; margin-top: -1em } See how we didn’t have to add a class to style the image, we used the fact that the image is a descendent of the vcard element, and a descendent selector. In my experience, the very widely supported, powerful descendent selector is one of the most underused aspects of CSS. So if you don’t use it frequently, look into it in more detail. We added some space to the right of the image, and pulled it up a bit closer to the top of the hCard, like this We also want to add some whitespace between the edge of the hCard and the text. We would typically add padding to the left of the containing element, (in this case the vcard element) but this would break our bottom left hand corner, like this That’s because the div element we added this bottom left background image to would be moved in by the padding on its containing element. So instead, we add left margin to all the paragraphs in the hCard .vcard p { margin-left: 1em; } (there is the descendent selector again – it is the swiss army knife of CSS) Now, we’ve not yet made the width of the hCard a function of the size of the text inside it (or “em driven” as we described it earlier). We do this by giving the hCard a width that is specified in em units. Here we’ll set a width of say 28em, which makes the hCard always roughly as wide as 28 characters (strictly speaking 28 times the width of the letter capital M). So the statement for our containing vcard element becomes .vcard { background-image: url(images/vcardfill.png); background-repeat: no-repeat; color: #666; font-family: ""Lucida Grande"", Verdana, Helvetica, Arial, sans-serif; width: 28em; } and now our element will look like this We’ve used almost entirely the existing HTML from our original hCard (adding just a little, and trying as much as possible to keep that additional markup meaningful), and just 6 CSS statements. Holiday Bonus – a downloadable vCard Did you notice this part of the HTML What’s with the odd looking url