FAHNZ

MODE

Feb 4 2010

Base CSS Font Sizes Gone Wild (plus bonus CSS reset!)

I’ve been working on my version of a CSS “reset” file lately trying to achieve a gentler reset than the big ones out there. Specifically, I don’t want to reset everything all the way to zero; I’d just like better control over what those defaults end up being (cross-browser of course).

So, I’ve got almost everything done on my reset when I get to the point of wanting to set the base body font size in the CSS. So, as I have done in the past, I looked to the internet for guidance on what the best practice is. So the internet tells me:

  • Set the base body font size to a percentage in the CSS to alleviate Internet Explorer text sizing issues. (yup, knew that already)
  • Always use “em” units for your subsequent font sizing. (of course – been doing that for years)
  • Your base font size percentage should be… (!)

What? There’s no standard out there among the CSS gurus as to what that base font value should be? I was surprised.

So, time to do my own investigating to determine what my base font size should be. Here’s a list of websites that I checked and their base body font sizes:

Curiously, Twitter, Facebook and Yahoo! all use pixels as their base font size:

  • Twitter (0.75em, but overridden to 11px almost everywhere)
  • Facebook (11px)
  • Yahoo! (13px) use px as the base font size.

I’ve seen the 62.5% value often as a means to set the default browser text size to 1em = 10px. Obviously for those who want to set their fonts in pixel sizes, but know they can’t do it directly. Seems that it would work pretty well. For a long time now, I’ve been using the base font size of 76% as based off of this post by Owen Briggs. Strange that there isn’t more of a consensus among the CSS elite, but I think I’ll stick with Owen’s standard. I mean, anyone who took the trouble to take 264 happy little screenshots on the subject of CSS typography deserves some serious recognition.

I still think that the default sizes for the headings could use some tweaking, but I have a CSS reset demo page as well as having the demo pages available in a zip file.


Dec 7 2009

JavaScript (jQuery) Text Resizer

First off, let it be known that I think that JavaScript-based text resizers suck. I firmly believe that the text size should be controlled by the user via the web browser controls. I’ve found that most clients want a JS-based text resizer because they think that it will make their website more accessible when, ironically, these types of resizers are not accessible by nature (since they require JS to work).

So, having seen poor implementations of this functionality in the past, I had a few requirements that I wanted my version of the text resizer to meet:

  1. Must be accessible or not be available at all.
    In other words, if it’s going to be non-usable or broken, then don’t even display it. There’s nothing worse to me that having something on a page that requires JavaScript to work, but doesn’t do anything at all to account for when a user does not have JavaScript. Especially when there is an incredibly easy way of addressing this (see below).
  2. Must account for the initial font-size and allow the user to return to that size
    The design mock-up that I received for this project showed that the text size controls would be a series of three letter “A” links, each larger than the previous. I decided that it made sense to make the smallest “A” represent the initial font-size. The subsequent links would add the ability for “bigger” and “biggest”.
  3. Must persist across page views
    I have seen many, many implementations of this that don’t even persist from one page to the next. That has got to be annoying if you’re really trying to use this feature.
  4. Must work on only specified areas of the design (as opposed to the whole page)
    This requirement was from the client and – in my opinion – is the closest thing to a good reason for implementing this type of functionality.

So, the first item on my list was “Must be accessible or not available at all” and was nice ‘n easy to implement. Simple solution that I’ve used in the past is to render the JavaScript-requiring-component with JS. If the user has JS, then JS will make the component available. If not, then it will never even be rendered. Simple! Now, I realize that this could be made to work server-side using AJAX or postbacks, but that was out of the scope of this particular project (not to mention getting to the point of needing to argue the downfalls of doing it this way to the client).

The third and forth items on my list were also easy. To get this to work only on specified areas of a page, I would make it work on only those elements that have a specific CSS class applied to them. To get it to work from page to page, I’d just store the requested size in a cookie. Easy-peasy!

What I found to be the most problematic once I got into this was accounting for the initial font-size when the page is first requested. I have my default font-size set in the CSS as 0.76em (which is around 12px). Using jQuery, most browsers would return the correct value in pixel units (12 point something), but – ever the oddball – Internet Explorer 7 would return some bizarre value in the vicinity of 600-or-so pixels. Needless to say, that ended up being a bit too big when the text was resized. So, researching on the ‘net showed be that this is a common problem and I didn’t come across a good, simple solution. The primary solution I came across involved measuring the height of a hidden div to get the font height pixels so that everything could then be rendered with pixel font sizes. So there was a lot of discussion out there of how to find out what the current pixel size is of the font.

The pixel size of the font seemed dangerous and irrelevant to me. Potentially dangerous since pixel sizes don’t scale well in early versions of IE (I know, I know, I have ridiculous – but oftentimes necessary – browser compatibility requirements). Irrelevant since I really don’t care what specific font size is shown initially since the user will just be wanting to make the font size “bigger” or “biggest”. All I care about is that the font size is bigger relative to the initial font size. After pondering and experimenting, I came up with the following solution: upon the font resize function, add an inner HTML element to the area being resized, then add a percentage value to that element to resize the text.

I’m sure there’s room for improvement and added flexibility, but it seems to be working out pretty well so far. Code below:

HTML:

Text Size:
  <a href="javascript:ResizeText(1);">A</a>
  <a href="javascript:ResizeText(1.2);">A</a>
  <a href="javascript:ResizeText(1.6);">A</a>

<div>
  <p>This is text that will get resized.</p>
</div>

JavaScript (using jQuery):

// Global Variables
var fontSizeArea = ".body-outer"; // use 'html' for entire page
var textResizeCookie = "textResizeFactor";
var originalFontSize;

// Initialization Function
$(document).ready(function() {
  $(".text-sizer").show();

  originalFontSize = $(fontSizeArea).css("font-size"); // remember the original font size
  if (originalFontSize == null) { originalFontSize = $("html").css("font-size"); }

  var savedResizeFactor = $.cookie(textResizeCookie);
  var resizeFactor;

  if (savedResizeFactor == null) {
    resizeFactor = 1;
  }
  else {
    resizeFactor = parseFloat($.cookie(textResizeCookie));
  }

  if (resizeFactor != 1) {
    ResizeText(resizeFactor);
  }
});

// Resize Text Function
function ResizeText(resizeFactor) {
  var wrapperClassName = "g-fs-wrapper"; // global font-size wrapper
  var newFontSize = (100 * resizeFactor) + "%";

  if ($("."+wrapperClassName).length > 0) {
    $("." + wrapperClassName).css("font-size", newFontSize);
  }
  else {
    $(fontSizeArea).wrapInner('<div class="' + wrapperClassName + '" style="font-size:' + newFontSize + '"></div>');
  }

  $.cookie(textResizeCookie, resizeFactor); // remember the new size
}

Jul 31 2009

Why Are We Coding for IE6 Again?

Internet Explorer 6 sucks. We all know it. We all hate it. We all Most of us still have to deal with it. This is a problem I had run into before and it took me forever to figure out how to solve it this time. May as well document it here so I (and hopefully anyone else) can find it easily next time.

The problem:
Links styled with a background image are incorrectly tiling that background image. Or to put it another way; IE6 is not properly rendering the background of an inline element has a no-repeat background set. The example below shows the same link style applied in different places on the same page. As you can see, it renders the area for the background image position and dimension correctly, but it repeats the image within the confines of the actual arrow image dimensions (where it should show up). Man, that’s weird to try to explain. Hopefully the image below helps.

The problem shown:

Examples of IE6 background repeat and positioning problem

The CSS code:

.more-link {
 padding-right: 15px;
 font-weight: bold;
 text-transform: uppercase;
 background: url(../images/common/readmore-arrow.gif) 100% 1px no-repeat;
}

The HTML code:

<a href="#">View more</a>

The solution:
The solution is stupidly simple. I had figured it out before on a previous project, but of course couldn’t remember what the solution was. I just remembered it was something simple to implement. Anyway, as I emphasized above, the problem seems to be that the no-repeat background is set on an inline element. I guess that confuses IE6. Go figure. The browser is coming up on being a decade old.

The solution shown:

IE6 inline background problem - fixed

The updated CSS code:

.more-link {
 display: inline-block; 
 padding-right: 15px;
 font-weight: bold;
 text-transform: uppercase;
 background: url(../images/common/readmore-arrow.gif) 100% 1px no-repeat;
}

Voila! Tell IE to keep the element inline, but treat it like a block. Plus it shouldn’t adversely affect other browsers. Problem solved.