Archive for the ‘CSS’ Category
Columns With Separator Border in CSS: The Easy Way
Monday, July 12th, 2010CSS comes with quite a few production faults. You can’t properly vertically align, and you can’t comfortably create columns in a website without hacks.
Creating two columns with a dividing border, with the border’s length depending on that of the longest column and without the use of background images or JavaScript, is also a non-standard task, because you can’t affect the height of one element based on the height of another.
In the image on the right there are two floated divs used to create columns. If there’s a border on the left column and shorter than the right column, the border will also be shorter.
The Required Result
The secret
Both columns have a border. The left column is displaced one pixel to the right. This way, the borders overlap, and the longest border reaches the bottom of the page.

Each column has its own border, but the left column is moved one pixel right, overlapping the right column
In general, the concept of moving element with negative margins or position is quite interesting and can be an effective solution to many problems. I’m sure I’ll deal with it in future posts.
Code
<style type="text/css">
#menu {
float:left;
border-right:1px solid #000;
width:150px;
padding:10px;
background-color:#6E919A;
}
#content {
float:left;
border-left:1px solid #000;
width:250px;
margin-left:-1px;
padding:10px;
background-color:#9BC9D1;
}
</style>
<div id="menu">Menu<br/>Menu<br/>Menu<br/>Menu</div>
<div id="content">Content<br/>Content</div>
OhBehave – Apply Behavior to Static/Dynamic Elements, Immediately
Wednesday, June 23rd, 2010Applying a behavior to an element is a very common task in web applications and rich web sites. Something like an element onload event that is called whenever it’s ready, regardless of whether it’s pre-created in the html, or dynamically added.
For example:
- Converting a dropdown list (<select> tag) to an AutoComplete/custom designed select control
- Converting input type=checkbox/radio into images
- Wrapping an element with a complex frame (rounded corners, shadows, opacity)
- A floating label on a textbox and hiding it on a value change or focus
The Common, Bad Solution
A standard solution will be waiting until the DOM is ready (a function that exists in every self-respecting JS library), finding all elements with a certain class and calling a JS function on that element that will attach the behavior.
Disadvantages of this solution:
- Sometimes, it takes a little while until the DOM is ready, and meanwhile, the element appears in its original, behavior-less form
- When elements are dynamically added to the DOM (innerHTML / createElement & appendChild) – the behavior must be applied again on all new elements, manually.
- A generic solution for dynamic elements is having an interval in which looks for these elements. However, this lookup is slow and the delay may cause flickering.
Code Sample for the Bad Solution:
function applyBehaviors() {
var elements=$.select(".behavior");
for (var i=0;i<elements.length;i++) applySpecificBehavior(elements[i]);
}
$.domready(function () {
applyBehaviors();
});
$.ajax("url.html",{
onSuccess:function () {
applyBehaviors();
}
});
Or, an interval:
setInterval(function () {
var elements=$.select(".behavior");
for (var i=0;i<elements.length;i++) {
if (elements[i]._behaviorApplied) continue;
applySpecificBehavior(elements[i]);
elements[i]._behaviorApplied=true;
}
},200);
(The functions $.select, $.domready and $.ajax can be found in any JS library).
The Desired Solution – OhBehave
OhBehave is a neat script that is responsible for applying behaviors to elements immediately, as soon as they are available, without waiting for the rest of the DOM to load. In addition, it also applies the behavior on new dynamic elements.
You can create new elements on the fly or set an element’s innerHTML with new html tags, without worrying about attaching behaviors. An <input type=”checkbox”> can be converted to image base on its .checked property as soon as it’s appended to the document.
If you use Ajax to get HTML from server, you shouldn’t be worried about wiring up events to elements.
As Event Delegation is good for attaching events to all elements of a certain type, OhBehave does the same for more complex behaviors.
How does it work?
For every browser I had to find a different solution, as each of which implements the desired functionality differently. Each of the implementations is a small browser-specific code that calls OhBehave.initialize, which receives an element and applies all behaviors needed.
The behaviors for that element are defined in its class attribute, each of which is prefixed with “oh-behave-” (optional). E.g. oh-behave-AutoComplete, oh-behave-WrapWithFrame.
Example for a behavior
OhBehave.behaviors["AlertTheTime"]=function (element) {
element.onclick=function () {
alert(new Date());
};
};
// or, as a global function -- function AlertTheTime(element) { ... }Implementations
Firefox (Gecko Engine) – XBL
XBL, or – XML Binding Language, is a markup language, based on XML, that is defined according to a W3C standard and is used for applying rich behavior to an element. XBL allows us to declare properties (including getters/setters), custom events (and to fire them), custom methods and custom style. The XBL is placed on an element using css:
.oh-behave { -moz-binding:url("oh-behave.xml#oh-behave"); }The XML structure:
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:html="http://www.w3.org/1999/xhtml">
<binding id="oh-behave">
<implementation>
<constructor>OhBehave.initialize(this);</constructor>
</implementation>
</binding>
</bindings>As for now, only the Gecko engine supports XBL, even though it’s a standard.
IE (Trident Engine) – HTC
HTC, or – HTML Component is Microsoft’s implementation for applying rich behavior to an element. It supports more or less the same as XBL.
Safari/Chrome (WebKit Engine) and Opera (Presto Engine) – The Event DOMNodeInserted
As WebKit/Presto didn’t include XBL yet (there are some mentions in the source code but it’s still turned off probably), I had to find a different solution.
The DOMNodeInserted event (a W3C standard) is fired any time an element is inserted dynamically (innerHTML / createElement & appendChild). Through this event I look for elements that should have the behavior. The lookup is done with querySelectorAll – a method of a document or element that gets a CSS selector and returns all elements for that selector.
For elements that are already in the document, I used the DOMContentLoaded event, which may cause a small flick but the engine is so fast that I barely believe it’s noticeable.
Code
// behavior example - assigns alert of the current time onclick
OhBehave.behaviors["AlertTheTime"]=function (element) {
element.onclick=function () {
alert(new Date());
};
};
// behavior example - adds a frame around an element
OhBehave.behaviors["WrapWithFrame"]=function (element) {
var frame=document.createElement("div");
frame.className="cornerized";
element.parentNode.replaceChild(frame,element);
frame.appendChild(element);
var corners=["tl","tr","bl","br"];
for (var i=corners.length;i--;) {
var corner=document.createElement("div");
corner.className="c "+corners[i];
frame.appendChild(corner);
}
};
<div class="oh-behave oh-behave-WrapWithFrame oh-behave-AlertTheTime">Auto apply behavior on existing element</div>
When the div appears on the screen, it obtains immediately the onclick event and being wrapped with a box with 4 corners.
Demo
In the demo page there are two behaviors applied on same element: 1) Wraps the element with a frame and some other elements, 2) Attaches a click event to show current date.
In addition, there’s a button that adds more elements, dynamically and the behaviors applied automagically.
Demo of OhBehave | Download Source
Attention! In case you only need to attach events, you should use the Event Delegation method.
Table Layout in CSS
Wednesday, June 23rd, 2010I’ve been in this situation quite often:
We have a list of elements that need to be laid out on the page in the following manner:
- Each element has fixed width / height.
- There are a number of elements in a row.
- There must be an equal space between any two elements.
Well, this is a classic case for a table! Yes! I can see it happening; with the right cellspacing and background color, it will be perfect.
NOT.
So, CSS.
The requirements are:
- Each item is 50×50 pixels.
- 15 pixels between items.
- 4 items in a row.
We’ll create a <ul> to contain all the items. Its width will be 245 pixels, to house 4 items and 3 spaces between them (4*50 + 3*15).
To create a list of items in a row we shall use float: left (or right) in order to place the elements on a particular side. Every time an item reaches the edge of the box in which it is contained, it will drop down to the next row.
To create the spaces between the items, we’ll use margin-right. And here is the catch:
As you can see, the spacing is created for each item.
Due to a lack of spacing on the right, the last block of each row drops down. Because of the bottom margins, there is superfluous space at the bottom of the container. Our design has gone wrong.
How about if we don’t want the last column to have a side margin and the last row a bottom margin?
The sophistication of CSS3 (nth-child) is yet to be here.
The Trick
We keep the margins.
We’ll enlarge the container <ul> to 260 pixels, so that it contains the right margin of the last box.
We create another wrapper div, hide the overflow and give it a width of 245 pixels, and inside we place the <ul> with our items. The <ul> with the items will actually flow on, but because we’ve “trimmed” it the new wrapper div, we won’t see the superfluous space on the side.
And what about the space at the bottom? We’ll give the <ul> containing the items a negative margin-bottom as large as the items’ lower margin.
Code
<style type="text/css">
.item-list-wrapper {
overflow:hidden;
width:245px;
border:5px solid #000;
font-family:verdana;
}
.item-list,.item-list>li { margin:0; padding:0; list-style:none; }
.item-list {
overflow:hidden;
width:260px;
margin-bottom:-15px;
}
.item-list li {
background-color:#ADCBDA;
width:50px;
height:50px;
margin-right:15px;
margin-bottom:15px;
float:left;
}
</style>
<div class="item-list-wrapper">
<ul class="item-list">
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
</div>
This example can contain as many <li>’s as you want, without harming the layout.
Table Layout in CSS – Example page




