We've moved!

TechKnack.blogspot.com has officially moved to TechKnack.net. You should be redirected in 3-5 seconds. Thank you.
Showing posts with label css. Show all posts
Showing posts with label css. Show all posts

July 12, 2008

Sticky Page Footers

Add this post to Del.icio.us. Del.icio.us (0 saved)

Occasionally you'll be coding out a site, and you want a "sticky footer", a footer that sticks to the bottom of the browser viewport or the bottom of the main content section, whichever is lowest.

There are a few notable sites that have posted methods for doing this, but the short answer is it doesn't work unless you meet certain requirements. Probably the most popular example (which is also the first google result for "sticky footer") is A CSS Sticky Footer. However, as the explanation page shows, the method uses extraneous markup to push the footer down below the content. Also, this method only works with static-height footers.

Another good example comes from AListApart: Exploring Footers. The method involves using relative positioning on a container and absolutely positioning the footer to the bottom of that container. Inexplicably, this works, though for my implementation, I used the body element as my wrapper. Unfortunately, you have to apply appropriate padding or margin to the bottom of the content div, which in turn squashes the idea of having a dynamic-height footer.

Given these examples, which are perfect for fixed-height footers, it seems sticky, dynamic-height footers are not meant to be under current browser implementations. If you're insistent on having a dynamic-height sticky, you'll have to go the way of the faux footer (along the lines of the faux columns, which I've always thought to be cheating :) ). I couldn't find any links talking about faux columns (in this sense, anyway), but one site which currently implements it is KilianValkhof.com. If you look into his code, you'll see that the background of the footer is actually set in the body.

May 11, 2008

Lists, Useful For More Than Menus

Add this post to Del.icio.us. Del.icio.us (0 saved)

I came across a page recently that uses ordered lists for the entire layout -- not just the menu. The entire layout is in two parts: one ordered list for the header/body/footer, and another ordered list for the three columns inside the body.

I find this to be an interesting approach to multi-column layouts. Better yet, the author claims that it works in all major browsers on the three major operating systems.

However, are ordered lists the proper elements to use in this case? Is it "semantically correct"? What about unordered versus ordered lists? It'd be terribly simple to convert the layout to work with unordered lists, but which is more "correct".

Regardless of correctness, though, "no floats, no divs, no clears" is rather appealing.

April 19, 2008

Alternative Link Underlining

Add this post to Del.icio.us. Del.icio.us (0 saved)

Ever seen the odd site that, instead of solid or absent underlining, has a dotted or dashed underline? Ever wonder how it's done? It's really simple: border-style.

All you need to do to get an alternative underlining effect is to, first off, hide the default underline with text-decoration:none, and then specify a bottom border for the affected links: a:link { text-decoration:none; border-bottom: black dashed 1px; } To make the effect stand out, you could also make the link and border separate colors, either on hover or all the time.

April 12, 2008

Pretty Up Your Forms with CSS

Add this post to Del.icio.us. Del.icio.us (0 saved)

Download Example

Let's face it: form elements au naturel are NOT pretty. So what do we do with them? We add a border thickness here, a border color there, leaving the whole thing largely unchanged. And still ugly. Time to change that.

I'm going to use the Tableless CSS Forms code provided by DynamicDrive's CSS library contributors. This gives us the basic layout and essential elements without too much trouble:

We'll start with the basics: borders and background. In Web 2.0, simplicity is king. Beveled corners? Sooo Web 1.0. Sooo not pretty. We'll make the borders solid, with uniform color, and thin to keep the simplicity. And we'll specify a white background to avoid any cross-browser issues: .cssform input, .cssform textarea { border:#999 solid 1px; background:#FFF; } A nice, neutral gray tones down the harshness of the input areas' borders, and the solid-1px all the way around eliminates any doubts as to where the areas begin and end.

Next we want to make it a li'l roomier. How do you like cramming text into zero-padding textboxes? .cssform input { padding:3px 5px; } .cssform textarea { padding:5px; } Here's when you start getting into trouble with the disparities in browsers' box models, though as long as the width of the elements isn't an issue, you should be fine.

Now that we've covered the foundation, time to break out the makeup: images! Using a very small, very subtle gradient image, we can add a simple inner shadow to each input field. While this is "adding features", I feel it actually adds to the feeling of simplicity: .cssform input, .cssform textarea { border:#999 solid 1px; background:#FFF url(formgrad.png) repeat-x top left; } The gradient image is a 1px wide by 15px high PNG image with a gradient of hex colors #EEEEEE (top) to #FFFFFF (bottom). The slightest difference in color makes for a very nice effect.

We could very well stop here -- all the form elements are styled nicely, even the submit and reset buttons. But why stop there when you can make the buttons intuitive as well? .cssform .submit { background:#FFF url(submitgrad.png) repeat-x bottom left; } .cssform .reset { background:#FFF url(resetgrad.png) repeat-x bottom left; } Here we use another technique found at DynamicDrive. This simply adds two other colored gradient images to the background of the appropriate buttons. Of course, you must add the appropriate classes to the buttons for this to work. If you want to take full advantage of CSS standards and leave IE6 and below behind in the dust, you could just use the attribute selector: .cssform input[type="submit"] { background:#FFF url(submitgrad.png) repeat-x bottom left; } .cssform input[type="reset"] { background:#FFF url(resetgrad.png) repeat-x bottom left; }

And there you have it. With no more than three images (or one, if you prefer), some very simple CSS, and an eye for simplicity, we've made our form elements nice looking.

Additional links:
Download the example
DynamicDrive: CSS Tableless Forms
DynamicDrive: Stylish Submit Buttons

April 4, 2008

Promote Standards Awareness with CSS Naked

Add this post to Del.icio.us. Del.icio.us (0 saved)

CSS Naked is a standards-awareness initiative led/organized by Dustin Diaz. On the specified date, April 9th, all participating websites will strip their sites of their CSS, allowing the world to see the underlying clean-code usability:

The idea behind this event is to promote Web Standards. Plain and simple. This includes proper use of (x)html, semantic markup, a good hierarchy structure, and of course, a good 'ol play on words. It's time to show off your <body>.

While I would love to participate in this, I wouldn't recommend it for Blogger users. The building blocks of Blogger blogs, widgets, produce all sort of irrelevant divs and such that are used exclusively as CSS hooks. Aside from the fact that the underlying code is NOT semantic, disabling styles on Blogger sites (well, this one anyway) is NOT pretty (or, for that matter, usable). If you must see the results of such an inadvisable act as disabling CSS, you can (using FireFox) go to View -> Page Style -> No Style. This will disable styles for the current page (or the current tab, I'm not exactly sure).

So, to reverse Dustin's little play on words -- sorry, you don't get to see my <body> :P

April 1, 2008

Got Mad Coding Skills?

Add this post to Del.icio.us. Del.icio.us (0 saved)

Think you got what it takes to slice up a PSD file into a valid and usable (X)HTML template? Then check out CSS Off, a contest that gives you the opportunity to do just that. At one minute past midnight CST on April 5, a PSD file will be uploaded for contestants to download. Contestants will have up to 24 hours to submit their completed entry.

Don't have Photoshop? Check out the GIMP! I'm hoping that the PSD file is GIMP-compatible. You could try to convert it one way (using an online service) or another (directly in the GIMP),but there's always the issue of unsupported layer effects getting messed up.

And, no, this is not an AFD trick. At least, I hope it isn't...

February 12, 2008

Progressively Enhance copyable code blocks

Add this post to Del.icio.us. Del.icio.us (0 saved)

I've employed a bit of progressive JS here on the blog to make it easier for readers to copy the blocks of code that I post. Go ahead, try it: click within the code block, and the entire thing is selected. Makes for pretty easy copying, rather than having to carefully select just the text inside the box...
// I'm code!! Copy me!! $ hello world // w00t...

The way it works

Here's how it works: I've defined a function which goes over every single <code> element on the page. For each code element, a textarea element is created and inserted into the DOM tree directly before the corresponding code element. Once a textarea is added to the DOM, it is hidden via CSS. The textarea is given, as child nodes, recursive clones of code's DOM child nodes. Then, the onclick event of the code element and the onblur event of the textarea are set to different functions. The code's onclick function hides the code element, un-hides the textarea element gives the textarea the focus, and selects the textarea's contents. The textarea's onblur function hides the textarea and un-hides the corresponding code element.

It's possible to have the script do this for all code elements on the page, but I've implemented it to only target those code elements to which I've given a class name of "copyable".

The CSS

The hiding-un-hiding tricks aren't possible without CSS. Well, they're possible, but such an implementation would make the JS much messier. Here I've used CSS to similarly style both code elements and elements with a class name of "codeenhance" (which is used to identify the inserted textareas).
.codeenhance, code { width:430px; color:#000; display:block; background:#eee; padding:0 10px; padding-bottom:1em; margin:0; border-width:3px 1px !important; border:#99f solid; overflow:auto; line-height:1.4em; font-family:monospace; font-size:1.1em; } .codeenhance, .copyable { height:250px; } code { white-space:pre; } .codeenhance { padding:0; } .codeenhance-off { display:none; } The first declaration is the main styling for the code elements. The height specification for .codeenhance and .copyable fix the height of copyable code blocks, so your 159 lines of copyable JS don't take up too much space. I've left the height out of the main declaration, to allow the other code blocks to expand/retract to their contents' size. The white-space declaration for code elements maintains the whitespace as you typed it. The padding declaration for .codeenhance fixes an interesting jumping issue with the textareas. And the display declaration for .codeenhance-off is what hides the appropriate items.

The Javascript

Here's the JS. The explanations are in the code comments ;)
// Enable click-select on code elements function enhanceCode() { // Get all code tags var codes = document.getElementsByTagName("code"); // loop over code tags for (i=0; i<codes.length; i++) { // working only on tags of class "copyable" if (codes[i].className.match('copyable')) { // for each tag, create a new textarea var text = document.createElement("textarea"); // copy the code's children over for (j=0; j<codes[i].childNodes.length; j++) { // special code for Blogger, to take care of extra br elements if (codes[i].childNodes[j].nodeName == "BR") text.appendChild(document.createTextNode('\r\n')); else text.appendChild(codes[i].childNodes[j].cloneNode(true)); } // set the initial classname // (use .className rather than .setAttribute('clas', 'blah') because IE6 // doesn't like the latter text.className = "codeenhance codeenhance-off"; // setup the onblur event text.onblur = decodex; // insert the textarea before the code codes[i].parentNode.insertBefore(text, codes[i]); // setup the onclick event codes[i].onclick = codex; } } } // this = code element; this.previousSibling = textarea element function codex() { // show the textarea this.previousSibling.className = this.previousSibling.className.replace(/ ?codeenhance\-off/, ""); // hide the code this.className = this.className+" codeenhance-off"; // focus and select the textarea this.previousSibling.focus(); this.previousSibling.select(); } // this = textarea; this.nextSibling = code function decodex() { // show the code this.nextSibling.className = this.nextSibling.className.replace(/ ?codeenhance\-off/, ""); // hide the textarea this.className = this.className+" codeenhance-off"; } window.onload = function() { // run the enhancement /after/ the window has loaded enhanceCode(); }

February 1, 2008

A well-designed website: many things to many people

Add this post to Del.icio.us. Del.icio.us (0 saved)

In my Advanced Web Design class at school, my professor asked us to post what we thought defined a well-designed website. I thought I'd share my answer here. I'm sure he wasn't expecting anything so involved as this :D

"What makes a well-designed website?" That's quite a question.

As a dabbler in web design, I would say a well-designed website is "good-looking". It should look somewhat elegant. The "Web 2.0 style" -- glossy buttons, spacious openness, minimalistic simplicity, and copious use of gradients -- comes to mind. I can't think of any sites that strictly adhere to all these points, but DynamicDrive is a good-looking site.

As an HCI-minded individual, a well-designed website is made by more than its layout. A well-designed website makes it obvious what the site's purpose is, what can be done on the site, how to go about doing it, etc. Again, simplicity is king, and clutter is sin. Content is easy to skim and understand. The layout does not make it difficult to navigate. If a feature breaks, the site will either gently tell the user so, and make it easy for the user to report the breakage; or the site will function in such a way that the user doesn't notice the difference, and the developer will be alerted. I think Digg is a fairly usable, well-designed site.

As a web developer at heart, a well-designed website is all in the code. Separation of structure, content, presentation, and functionality is something to be strived for. It should be built as follows:

  1. First build a mock page (with the final site's design in mind) which contains either mock or real content, and only structure-oriented HTML markup. Presentational markup is sin :) This page is not design-oriented; its only purpose is to structure the page's content in a semantically meaningful way. Any tags that do not directly relate to the structure and/or content of the page should be struck down with a flaming sword of death. Organize things in such a ay that they flow logically along the page.
  2. Develop the CSS in an externally linked file. Introduce any design-specific images through the CSS, if possible (and it should be possible). Strive for cross-browser compatibility within the CSS, making the site look as similar as possible from one browser to the next. If any additional markup is required for the design of the site, the CSS should be developed to make the site look good without it; if still necessary, the necessary markup can be added through the next step. Use what you have to get what you want.
  3. Develop the functionality (using JavaScript) in another externally linked file. Nonintrusive javascript should be used, progressively enhancing the site after it has loaded. Nonintrusive javascript should also be used to add any necessary additional markup to be used by the CSS. Again, use what you have to get what you want.
  4. If possible, convert the finished page layout into a template, and use a server-side language to fill it with dynamic content.
  5. Finally, when all is said and done, pull up the page in a browser, and make sure everything works. Turn off javascript, refresh, and make sure everything works. Turn off css, refresh, and make sure everything works. Then browse the web for a while....and see if it works :)
According to these steps, a well-designed website will work across browsers, degrade gracefully in older browsers, respect the wishes of those with Javascript turned off. There are lots of websites that use this methodology (using only semantically-meaningful html, etc). One well-designed website in this case is Dynamix Labs. It doesn't seem that they use any javascript, and if you turn off CSS, the site is still very readable.

As a user, I want information, and I want simplicity in doing what I want to do. A lot of the time, I want information that I can talk about in my blog. I use google as my main go-to source for finding things. If I find a site that gives me good information on a regular basis, I want to be able to subscribe to its RSS feed, or something similar. If I find a site that I come back to on a regular basis (whether I be forced to, or do so of my own free will), I want to be able to customize my experience on that site. I want to be able to change the colors, the landing page content; anything and (usually) everything, I want to customize it to better serve my way of doing things.
One service that I use on a daily basis is Google Reader (you'll have to sign in to your google account), a web-based RSS aggregator. It features "folders" that you can use to organize your feeds, drag-and-drop re-ordering of feeds, and very easy-to-use methods of subscribing and unsubscribing from feeds. Another service that I use regularly is Netvouz, a social bookmarking site. I chose Netvouz over other bookmarking sites because of its folder organization feature. You can organize your bookmarks according to category (and sub-category) and make certain bookmarks private. It's also easy to delete or edit my existing bookmarks, and really easy to add new bookmarks using the Netvouz firefox extension.

I must say, though, that my most frequently used and favorite thing is FireFox. It is customizable in (almost) every way possible; its functionality is infinitely extendable through extensions, which anyone familiar with XML and Javascript can write. It has excellent support for standards; the upcoming FireFox 3 is said to have passed the Acid2 test, which is huge for web developers.

As you can see, from my point(s) of view, a well designed website can and should be many things to many different people.

So, what do you think? What makes a website "well-designed"? What are some examples of well-designed websites?

Note: References to certain things "being sin" should not be taken literally. Putting presentational markup on your page will not send you to hell. Nor will avoiding clutter send you to heaven. These are just my personal pet peeves :)

January 14, 2008

CSS trick - two background images

Add this post to Del.icio.us. Del.icio.us (0 saved)

Download Example

While using what I'm sure is my own idea of progressive enhancement on a web page, I came across an interesting situation: I wanted two background images, rather than one. My first background would be a general tiled image, to give the site's background a nice texture; the second a vertically-repeated image on the left-hand side, to be used in conjunction with a floating nav menu.

Now, while CSS3 is purported to support up to 8 background images -- no doubt to make rounded corners and other fancy borders easier for coders -- the problem is that, to the best of my knowledge, IE and FF don't yet support this feature. Besides that, IE6 and lower never will. And I'm not even sure this feature will be usable for what I want, anyway.

So, I had to have (ok, really, really wanted) the left-hand background, and, IMO, the page looked too bland without some texture on the general background. As I already had the structure of the page decided upon (and, as such, couldn't modify it for presentational purposes), I started looking at what I had to work with. There was obviously the body tag, but there was nothing much else to work with...besides the html tag itself.

I already had the vertical background applied to the body tag, so I started by removing the background color from body (so the html background could show through). I then applied the same background color and the new background image to the html tag:

html { background:#000 url("tiled.png"); } body { background:url("vertical.gif") repeat-y; background-position:75px top; }

And, whaddaya know, it worked! Unfortunately, it seems that declaring the html element's style in my CSS changes the basic behavior of the body element, making it more like a containing div. The result: there's a margin around the content, and the vertical background only goes to the end of the content. Yuck.

So, the first thing to do is fix the ugly margin. Easy enough: set body's margin to 0 , as well as body's padding for good measure. Next, fix body's background. Currently, the background stops at the end of the content area. Not a problem if the content causes the window to scroll, but not pretty if there's not enough content. I figure this should be easy enough to fix, just set body's height to 100%. This works well enough...in IE6. Strangely, FireFox 2 doesn't take so kindly to it. Changing the body's height to "auto" works alright, for both browsers, for overflowing content, but not for short content. A height of "auto" and a min-height of 100% works excellently in FireFox 2...but, again, IE6 doesn't know how to treat min-height. Good grief.

So, I enter the realm of CSS hacks. Using a min-height hack combined with advanced CSS selectors that aren't understood by IE6 and less, I combine the methods that worked for each browser into a series of rules that are "browser-filtered" - one browser uses one method, while another browser uses the next.

html { background:#000 url("tiled.png"); /* Height is 100%, so the body can be 100% */ height:100%; } body { background:url("vertical.gif") repeat-y; background-position:75px top; margin:0; padding:0; /* Height is 100%, so the tiled BG will tile all the way down the page, not just as far down as the page's content (when the content's height is less than the window's height) */ height:100%; } /* Hackety-hack-hack... FF2, with the above code, will only display the repeat-y image for as high as the window's viewport is; higher content (upon scrolling) will not have the bg. This "hack" makes the tiled background work properly in FF2. This type of "advanced selector" is not understood by IE6...dunno 'bout IE7. */ html>body { min-height:100%; height:auto; }

The common html code works fine on both browsers. It's only the body's height issue that needs resolved. The IE6 code is given in the body code; both browsers will see this and understand it. However, when they get to the html>body statement, IE6 says "wha??" and drops the rule, whereas FF2 says "ok..." and applies the appropriate styles to the body tag, overriding the earlier-mentioned height.