Showing posts with label css. Show all posts
Showing posts with label css. Show all posts

Thursday, November 18, 2010

Making readonly form fields easier to identify

Readonly form controls, or "disabled" in the HTML parlance, can be hard to distinguish from fields users can type into. Firefox and IE are doing an equally bad job, and making the distinction would be close to impossible if the field was empty to start with:

How default readonly input and text area are rendered by IE 7 and Firefox 4

Adding a grey background to disabled fields is a good way to help users distinguish between readonly (disabled) and read-write (non-disabled) form controls:

How readonly input and text area are rendered by IE 7 and Firefox 4 using a background color

IE 7 onwards supports CSS attribute selectors, so if you don't need to support IE 6, the following CSS will do the trick:

textarea[disabled], input[disabled] { background-color: #eee }

However, if you need to support IE 6, you'll need to decorate your readonly form controls with a class. Some frameworks, such as some XForms implementations, do this automatically for you. For instance, if all your readonly form controls are automatically inside an element with the class xforms-readonly, you can write:

.xforms-readonly textarea, .xforms-readonly input { background-color: #eee }

Friday, September 25, 2009

IE6 Bug: Relative Box After Float Doesn't Show

Consider the following code where you have a floated element (in this case a label), followed by a div with position: relative, containing an input field with a width: 100%.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<style type="text/css">
.label { float: left; }
.div { position: relative; }
.input { width: 100%; }
</style>
</head>
<body>
<label class="label">Label</label>
<div class="div">
<input class="input" type="text"/>
</div>
</body>
</html>
The issue is that on IE6, the input field doesn't show:

This bug has been resolved in IE7, and you can easily work around it in IE6 by forcing the box to "have layout" (in IE, elements with position: absolute have layout, but elements with position: relative don't necessarily have layout). My favorite way for doing so it to add a *zoom: 1 on the box, which will give you the expected result:

Thursday, September 24, 2009

CSS: Why Use Relative Positioning?

The CSS position can have 4 values: static (the default), relative, absolute, or fixed. IE6 doesn't support fixed positioning, so that leaves you with 3 values. Static positioning leaves elements in the normal flow, so you are left with 2 really interesting values:

  • relative – Leaves the element in the normal flow, but allows you to move it relative to that position using top and left.
  • absolute – Takes the element out of the normal flow, and positions it relative to the top left corner of its closes positioned ancestor, i.e. the closest ancestor with a position set to relative or absolute (or fixed).
With this in mind, there are 2 main reasons to use a relative positioning:
  • Obviously, you might want to move an element relative its positioning in the normal flow. So you would use position: relative in conjunction with a top and left on an element. But in my experience, this is rarely needed.
  • More often, you want to position an inner box relative to an outer box. You do so by using position: relative on the outer box and position: absolute on the inner one, for instance to produce the result shown below, with the corresponding HTML immediately following:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<style type="text/css">
.outer { position: relative;
border: 2px solid #999; }
.inner { position: absolute; top: 1em; left: 1em;
border: 2px solid #666; }
</style>
</head>
<body>
Outside outer
<div class="outer">
Outer
<div class="inner">Inner</div>
</div>
</body>
</html>
If you were to ignore the position: relative on the outer element, you would get:

Monday, January 19, 2009

HTML/CSS: Table inside table getting out containing cell with IE

Consider this table with a width: 100% displayed inside a table cell:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<table style="width:100%; border: 1px solid red">
<tr>
<td>
<div style="padding-left: 3em;
padding-right: 3em">
<table style="width: 100%;
border: 1px solid blue">
<tr>
<td>Gaga</td>
</tr>
</table>
</div>
</td>
</tr>
</table>

</body>
</html>

With IE, the table "gets out" of its containing cell. Notice that it is as if the width of the inner table was calculated without taking the padding into account, but its position inside the cell was taking the padding into account:
HTML_CSS_ Table inside table getting out containing cell with IE - Google Docs.png
The expected result is rather:
ff-ok-1.png
There are two ways to fix this:

The clean way – Switch the rendering from quirks mode to strict mode by changing the doctype. If you can, I'd recommend you do this. This means that in the above code, you would just replace the doctype declaration with:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

The workaround way – Instead of defining the padding on a div, you put it directly on the outer cell, and remove the div, which gives you the following code.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<table style="width:100%; border: 1px solid red">
<tr>
<td style="padding-left: 3em; padding-right: 3em">
<table style="width: 100%;
border: 1px solid blue">
<tr>
<td>Gaga</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>