Wednesday, March 31, 2010

CSS efficiency tip: use a single stylesheet file for multiple media

The way most people link CSS intended for different media types, such as screen, print, or handheld, is to use multiple files. The files are then linked either through link elements with a media attribute or through @import statements with one or more media types specified.

There is nothing wrong with splitting your CSS into multiple files and linking them this way (I currently do that here on this site), but there are two drawbacks: it leads to more HTTP requests from the browser to the server and the need to maintain multiple CSS files.

Some people like splitting their CSS across several files, and not only for different media but for different sections of a site. I have tried working like that and while it may work well for some, it most definitely does not suit my workflow. To each his own, but the fewer CSS files I have to keep track of, the faster I work.

Luckily for me and others who feel the same way there is a way to put all of your CSS into a single file.

Enter the @media at-rule

An @media rule lets you group CSS rules by media type in the same file. Any rules outside @media rules apply to all media type that the stylesheet itself applies to.

Here is an example stylesheet that uses @media rules:

  1. body {
  2. color:#444;
  3. background-color:#fff;
  4. }
  5. @media screen, projection {
  6. body { background-image:url(background.png); }
  7. }
  8. @media print {
  9. body { color:#000; }
  10. }
  11. @media handheld {
  12. body { color:#0f6517; }
  13. }

Assuming that the above rules are in a CSS file that applies to all media, the following will apply:

  • For the screen and projection media types, text will be dark grey and the background will consist of a repeated image.
  • For the print media type, text will be black on white.
  • User agents that apply the handheld media type will render dark green text on a white background.
  • For all other media types, text will be dark grey on white.

This may or may not work for you, but personally I’ve found that doing this leads to less redundancy and reduces the risk of one or more media types being overlooked when I make changes to the CSS.

 

Copyright http://www.456bereastreet.com/archive/201002/css_efficiency_tip_use_a_single_stylesheet_file_for_multiple_media/

CSS3 Zebra Striping a Table

tbody tr:nth-child(odd) {

   background-color: #ccc;

}

 

Style Override Technique

p {

   font-size: 24px !important;

}

 

Standard CSS Image Replacement

h1#logo {

   width: 200px; // width of image

   height: 100px; // height of image

   background: url(../path/to/image.jpg);

   text-indent: -9999px;

}

 

Tuesday, March 23, 2010

Absolute Positioning Inside Relative Positioning

A page element with relative positioning gives you the control to absolutely position children elements inside of it.

To some, this is obvious. To others, this may be one of those CSS “Ah-ha!” Moments. I remember it being a big deal for me when I first “got it”.

Here is a visual:

The relative positioning on the parent is the big deal here. Look what would happen if you forgot that:

Might not look like a big deal in this small example, but it really is a significant change. What is happening is the absolutely positioned elements are positioning themselves in relation to the body element instead of their direct parent. So if the browser window grows, that one in the bottom left is going to stick with the browser window, not hang back inside like his well behaved brother from the first image.

Once you “wrap” your head around this concept (rim-shot) you will find little uses for it all over the place, and start noticing examples of other places using it. It’s like when you learn a new word and then you start hearing it everywhere. Yeah.

Grid Accordion with jQuery

Accordions are a UI pattern where you click on a title (in a vertical stack of titles) and a panel of content reveals itself below. Typically, all other open panels close when the new one opens. They are a clever and engaging mechanism for packing a lot of information in a small space.


Basic accordion from jQuery UI

One way to look at an accordion is like a collapsed single column of a table. I was recently building a page for a client site, where the information that they provided really made sense to present as a table. But it was too much information to view all at once. I thought it would have been overwhelming visually. I also thought that it was most likely that people visiting this page would know what they needed right away, so having them click once to get it seemed pretty reasonable. So, a table of accordions!

Another consideration in this table I was building is that there was enough columns that each individual column (should they have been equal width in the space available) wasn’t very wide, maybe 150px. Some of these cells contained several paragraphs of text. A cell 150px wide with several paragraphs of text would awkwardly tall. Hence, the Grid Accordion is born!

The Grid Accordion works with the same theory as most other accordions. Only one cell is open at a time. The big thing is that the column of the current open cell expands to a reasonable reading width.

You can view and download the example at the end of this article. I’ll go through some of the important bits next.

HTML: Classic use of the definition list

Accordions are perfect semantic examples of definition lists. A quick review of those:

<dl>
   <dt>Title</dt>
   <dd>Information about that title here</dd>
   <dt>Another Title</dt>
   <dd>Information about that other title here</dd>
</dl>

Our grid accordion will be made up of divs floated into a horizontal row. Each div contains the title for the column and an image, as well most importantly the definition list itself. Sample of one of those divs:

<div class="info-col">
 
        <h2>Batman</h2>
 
        <a class="image batman" href="http://jprart.deviantart.com/">View Image</a>
 
        <dl>
          <dt>Super Power</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
          <dt>Costume</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
          <dt>Morality</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
          <dt>Sidekicks</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
          <dt>Vehicles</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
          <dt>Weaknesses</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
        </dl>
 
</div>

CSS: trying to stay accessible

Most of the CSS is just simple setup and not really worth covering here (full CSS file here).

One aspect that is worth covering those is accessibility. We need to “hide” all the information panels of the table by default. One of the ways we could do that is to set the dd elements to display: none; in the CSS. This is a seriously accessibility problems though, as many screen readers will obey that CSS and completely remove that information.

Instead, we can “hide” the cells by just kicking them outside the browser window.

dd { position: absolute; top: -9999px; left: -9999px; }

This is a classic technique. In fact, it’s pretty common to see those exact CSS properties and values with a utility class name like this:

.screen-reader-text { position: absolute; top: -9999px; left: -9999px; }

We have another concern though. We’re going to be using some jQuery animations to slideUp and slideDown the info cells. So we can’t have them kicked off the page for typical viewers. We’ll move the cells back when the JavaScript first runs and then have the JavaScript hide them.

The thing about the slideDown jQuery function is that it works best when it already knows what height the element originally was before it was closed or hidden, so it can smoothly animate itself back to that original height. If we used display: none; in the CSS, this function would have no idea how tall those cells are supposed to be. Kicking them off the page instead means that the original height will be calculated, keeping that animation as smooth as it can be. We just need to make sure that the cell is set to its “full” width so the height is calculated at the width the cell will be when it’s visible.

dd { width: 299px; position: absolute; left: -9999px; top: -9999px; }

So at this point we have an accessible page of information, in that screen readers should be able to get all they need, and regular users have a smoothly operating system. However one thing that isn’t fully addressed is simply having JavaScript turned off. In that scenario, the information cells are still hidden by CSS. Personally, I’m far more concerned about accessibility than I am about people who browse around with JavaScript turned off and a torch to bear. However if you are, feel free to either 1) Put in a <noscript> message or 2) remove the CSS hiding and just let there be a bit of a flash of content before the JavaScript hides the cells.

CSS: Fun with CSS3

The CSS3 pseudo class selector :nth-of-type is particularly useful with definition lists. Because the dt and dd elements alternate, and actually can be repeated or in any order, :nth-child would be a non-maintainable way to go. Let’s color the cells of the table using :nth-of-type

dt:nth-of-type(1) { background: #b44835; }
dd:nth-of-type(1) { background: #b44835; }
 
dt:nth-of-type(2) { background: #ff7d3e; }
dd:nth-of-type(2) { background: #ff7d3e; }
 
dt:nth-of-type(3) { background: #ffb03b; }
dd:nth-of-type(3) { background: #ffb03b; }
 
dt:nth-of-type(4) { background: #c2a25c; }
dd:nth-of-type(4) { background: #c2a25c; }
 
dt:nth-of-type(5) { background: #4c443c; }
dd:nth-of-type(5) { background: #4c443c; }
 
dt:nth-of-type(6) { background: #656b60; }
dd:nth-of-type(6) { background: #656b60; }

For the rabble-rabble-IE-compatibility crowd, go ahead and add extra class names to the cells and do your coloring with those hooks.

One of the bits flair we are going to add is highlighting the current column. The class name of “curCol” will be applied and removed as needed via JavaScript. The current column will have a shadow around it, which of course is the perfect use for box-shadow:

.curCol { -moz-box-shadow: 0 0 10px rgba(0,0,0,0.2); -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.2); z-index: 1; position: relative; }

While I was playing with this, I originally tried using some transforms to scale up the size of the current column. Ultimately I didn’t like the look (one pixel lines look awful when scaled). I liked the shadows much better, but I found that the right edge of the shadow was being cut off the the next column. It was because that next column sat slightly above the current one in terms of vertical stacking order. Hence, the curCol class having the z-index and relative positioning, to make sure it sits on top of the others.

Randomly, I also discovered that the transform property also solved the problem. As in, setting -moz-transform: scale(1); (which scales something to 100%, or basically, does nothing to unscaled elements) also worked by making the shadow visible. In other words: using transforms on elements affects their vertical stacking order. I’m just not sure how it all works exactly quite yet.

jQuery JavaScript

Again I won’t cover every line of this (you can see the full file here). Here is the logical structure though:

  1. When a <dt> is clicked…
  2. If it’s the currently active cell, do nothing
  3. Otherwise…
  4. Close all open cells
  5. Shrink old title
  6. Enlarge new title
  7. Open new cell
  8. Mark the current column
  9. Make sure current column is expanded and others are shrunk

Couple of interesting things…

I would have normally used the .live() function to handle the clicks on the dt elements. But the newfangled hip way to handle this in jQuery is using .delegate()

$("#page-wrap").delegate("dt", "click", function() {
  // do stuff
}

Where live would have to watch the entire document for clicks, delegate limits that watching to only the page-wrap, which is more efficient.

I showed this to Doug Neiner, and he also suggested that clicking on the photos in each column would only open the column. Then if clicked again, they would actually go to the artist’s website (where the href of each image links to). The trick here was to prevent the default action (going to the link) when clicking on an image if it’s not the current column. Instead, divert the click to the first title in that column (which will open it). We can use delegate for this again:

$("#page-wrap").delegate("a","click", function(e) { 
 
    if ( !$(this).parent().hasClass("curCol") ) {
        e.preventDefault();
        $(this).next().find('dt:first').click();
    } 
 
});
 
Copyright : http://css-tricks.com/grid-accordion-with-jquery/

 

Thursday, March 18, 2010

Internet Explorer 9 Platform Preview Released

Microsoft today announced further details of their forthcoming Internet Explorer 9 browser, along with the first platform preview for developers, at their MIX Conference 2010.

Amongst the announcements comes increased support for CSS3, with support promised for CSS3 Selectors, Namespaces, Colors, Values, Backgrounds & Borders and Fonts, along with increased support for HTML5 and improvements in JavaScript performance.

The platform preview, downloadable from the Internet Explorer website, comes with a number of demonstrations including those for CSS3 border-radius and selectors. The preview also scores an impressive 578/578 on our CSS3 Selectors Test and an improved 55/100 on the Acid 3 test, with further improvements promised before the final release.

You can read more on the Internet Explorer blog, or download the platform preview here.

Copyright: http://www.css3.info/internet-explorer-9-platform-preview-released/

Meet the Pseudo Class Selectors

Pseudo class selectors CSS selectors with a colon preceding them. You are probably very familiar with a few of them. Like hover:

a:hover {
 /* Yep, hover is a pseudo class */
}

They are immensely useful in a variety of situations. Some of them are CSS3, some CSS2… it depends on each particular one. Outside of IE, they have great browser support. In IE land, even IE8, support is pretty barren. However, the IE9 preview has full support of them. The link-related ones work but not much else. Let’s take a brief look at each one of them. Don’t worry, there isn’t that many.

Link-related pseudo class selectors

:link – Perhaps the most confusion-causing link-related pseudo selector. Aren’t all <a>’s links? Well not if they don’t have an href attribute. This selects only those that do, thus is essentially the same as a[href]. This selector will become a lot more useful should any-element linking become reality.

:visited – Selects links that have already been visited by the current browser.

:hover – When the mouse cursor rolls over a link, that link is in it’s hover state and this will select it.

:active – Selects when the link while it is being activated (being clicked on or otherwise activated). For example, for the “pressed” state of a button-style link or to make all links feel more button-like.

There is a fun technique to remember all the link pseduo class selectors. Look at the first letter if each: LVHA … LOVE HATE.

Input & link related pseudo class selectors

:focus – Defining hover styles for links is great, but it doesn’t help out those who used keyboard navigation to get to the link. :focus will select links that are the current focus of the keyboard. This is not limited to links, but can be used (and really should be used) on inputs and textareas as well. Some would tell you to define a :focus style for anything that has a :hover style.

Copyright : http://css-tricks.com/pseudo-class-selectors/

Wednesday, March 10, 2010

Perfect Full Page Background Image

Technique #2

Big thanks, as usual, to Doug Neiner for this alternate version.

Here, we can use CSS with no JavaScript fixes, and the image is just an inline image with a class name of “bg” and no extra markup. That’s a big win for all the folks unhappy about the extra markup.

The only caveat is that it doesn’t quite meet all the requirements layed out about, in that it doesn’t center in IE 7, doesn’t work at all in IE 6, and may not always be proportionate depending on the original image size. BUT, since it’s simpler and bug-free, it’s defenitly a solid option. 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){
img.bg {
left: 50%;
margin-left: -512px; }
}

div#content {
/* This is the only important rule */
/* We need our content to show up on top of the background */
position: relative;

/* These have no effect on the functionality */
width: 500px;
margin: 0 auto;
background: #fff;
padding: 20px;
font-family: helvetica, arial, sans-serif;
font-size: 10pt;
line-height: 16pt;
-moz-box-shadow: #000 4px 4px 10px;
-webkit-box-shadow: #000 4px 4px 10px;
}

body {
/* These rules have no effect on the functionality */
/* They are for styling only */
margin: 0;
padding: 20px 0 0 0;
}

Monday, March 8, 2010

Unicode Characters for Class Names

Reader Kartlos emailed me in pointing to me to an interesting article by the great Mr. Snook from a few years back. I don’t think I had seen it before and it’s a bonafide “CSS Trick” so I thought I would share.

The idea is that you can use unicode characters (read: fancy symbols) for class names in your HTML, and even use write CSS selectors with those same characters.

< div class="♫">
A.A. Bondy
I Can See The Pines Are Dancing
< /div>

.♫ {
display: block;
background: #eee;
padding: 5px;
}

Pretty cool eh? I’d call my example above perfectly semantic as well, since the div with the music note class name is marking up a musician and song. Possibly even more semantic, as a music note symbolizes music moreso than any English word.

I put together a super simple demo page that shows it working. Oh, and yes-it-works-in-IE6™ & yes-it-validates™
But…

One funny thing? View the source on that page. I use PHP includes for the headers and footers of all my demos, and because of the character encoding (?) of that page the PHP doesn’t run it just sits there as text.

That ain’t right.

Coda does warn you first.

Weird eh? If you know how this could work both ways, let me know.
Other uses

Jonathan presented (in his original article) and idea for targeting the corners of a box.

< div class="□">
< div class="┌">
< div class="┐">
< div class="└">
< div class="┘">
content
< /div>
< /div>
< /div>
< /div>

Remember back a few years ago most of us were rocking rounded corners with nested divs and images like that! The corners symbols are clever, but I could see the < div class="□"> being used for like “container” or “box” style classes today, or, perhaps best of all, the clearfix.

I posted a little code clip of this over on Forrst (sorry I know most folks don’t have accounts there yet) and a guy named Aaron had a funny idea. Using upside down writing to be annoying! id='ɹǝpɐǝɥ', id='ɹǝddɐɹʍ', id='ɹǝʇooɟ'

Copyright : http://css-tricks.com/unicode-class-names/

Wednesday, March 3, 2010

How to shake your browser

Just paste below code in address bar


javascript:function Shw(n) {if (self.moveBy) {for (i = 35; i > 0; i–) {for (j = n; j > 0; j–) {self.moveBy(1,i);self.moveBy(i,0);self.moveBy(0,-i);self.moveBy(-i,0); } } }} Shw(6)