Archive for the ‘HTML & CSS’ Category.

Handling input maxlength using knockout

I set out to handle maxlength with the following goals:

  • Set maxlength on an input field. That took about 10 seconds.

This wasn’t sufficient however. It had two problems:

  1. This prevents the UI from going over the maxlength, but not code. I preferred a solution that did both.
  2. Once the maxlength is reached, there is no indication of why the next character typed is ignored. I wanted the textbox to flash red.

So I decided to do the following:

  1. Have knockout handle the max length and not have maxlength in the html.
  2. Have knockout change the css style for 3 seconds.

Knockout allows for something called extenders. I quickly saw extenders as the way to solve my problem. I followed the documentation and modified the example for my needs. I used Plunker to develop this solution and have a working model here:

http://plnkr.co/edit/9SZzcIPUSwWjBttHDQ64

My extender is as follows:

ko.extenders.maxLength = function (target, maxLength) {
    var result = ko.computed({
        read: target,
        write: function (val) {
            if (maxLength > 0) {
                if (val.length > maxLength) {
                    var limitedVal = val.substring(0, maxLength);
                    if (target() === limitedVal) {
                        target.notifySubscribers();
                    }
                    else {
                        target(limitedVal);
                    }
                    result.css("errorborder");
                    setTimeout(function () { result.css(""); }, 500);
                }
                else { target(val); }
            }
            else { target(val); }
        }
    }).extend({ notify: 'always' });
    result.css = ko.observable();
    result(target());
    return result;
};

Now, as you see, I set the css to errorborder, then I remove it 500 milliseconds (1/2 second) later. In order to make this work, I need an errorborder css style. Here is my first quick stab at that.

.errorborder {
  outline: none;
  border: 2px solid red;
}

.errorborder:focus {
  outline: none;
  border: 2px solid red;
  border-color: red;
  box-shadow: 0 0 3px red;
}

The user will see the border of the text box go red for half a second as they try to type more. Having validation text pop-up saying that maxlength has been reached can be done with this as well, but is probably not necessary. This red border should be sufficient visual feedback.

Html and css for simple banner layout

As many of you know, html and css still hasn’t figured out how to make layout simple and easy. No wonder banners are images. Trying to do a banner that isn’t an image is like beating your head against the wall.

Here is a very basic and very common use case:

  • Banner should not be a full-width image.
  • There is html content on the left that is left justified, html content in the center that is center justified, html content on the right that is right justified.
  • If the screen shrinks, the content in the middle and the right should not wrap.

Failure 1 – The intuitive approach

<div id="frame-banner" style="min-width: 800px">
  <div style="float: left; min-width: 200px">Left Content</div>
  <div style="float: center; min-width: 400px">Middle content</div></div>
  <div style="float: right;min-width: 200px">right content</div>
</div>

Well, even though it seems intuitive to have something float in the center, float: center doesn’t exist, so that just doesn’t work. Would have been cool. I of course, knew float: center didn’t exist.

Left Content
Middle content
Right content

 

Failure 1 – Simple divs

So let’s actually spend some time trying to make this work. Here is what I actually thought should work. Unfortunately, it doesn’t. Some weird formatting happens.

<!DOCTYPE html>
<html>
<head>
<title>html fails at layout</title>
</head>
<body>
<div style="width: 100%;height: 100px;background: gray;margin: 0;padding: 0;">
    <div style="width: 800px;margin: 0 auto;height: 100%;">
        <div style="width: 25%;height: 90%;display: inline-block;background: lightblue;"><div style="background: blue;color: white;margin: 10px;height: 80%;">left<img alt="Image Alt" style="width: 32px; height: 32px;" /></div></div><!-- no space
     --><div style="width: 50%;height: 90%;display: inline-block;background: orange;text-align: center;"><div style="width: 25%;margin: 10px auto;background: blue;color: white;height: 80%;">middle</div></div><!-- no space
     --><div style="width: 25%;height: 90%;display: inline-block;background: lightblue;text-align: right;"><div style="background: blue;color: white;margin: 10px;height: 80%;text-align: right;">right</div></div>
    </div>
</div>
</body>
</html>

I added some hacks to eliminate spacing that shouldn’t exist, but does.

left
middle
right

That looks so good. You think that is going to work right?

Well, let’s add an image and see how that works.

<div style="width: 100%;height: 100px;background: gray;margin: 0;padding: 0;">
    <div style="width: 800px;margin: 0 auto;height: 100%;">
        <div style="width: 25%;height: 90%;display: inline-block;background: lightblue;"><div style="background: blue;color: white;margin: 10px;height: 80%;">left<img alt="Image Alt" style="width: 32px; height: 32px;" /></div></div><!-- no space
     --><div style="width: 50%;height: 90%;display: inline-block;background: orange;text-align: center;"><div style="width: 25%;margin: 10px auto;background: blue;color: white;height: 80%;">middle</div></div><!-- no space
     --><div style="width: 25%;height: 90%;display: inline-block;background: lightblue;text-align: right;"><div style="background: blue;color: white;margin: 10px;height: 80%;text-align: right;">right<img alt="rss" src="http://www.rhyous.com/wp-content/plugins/social-media-widget/images/default/32/rss.png" /></div></div>
    </div>
</div>
left
middle
rightrss

See, as soon as you try to use this layout by adding an image, the layout breaks. Do they do any layout testing in browsers? I’ve heard rumors that the W3C doesn’t believe in supporting layout.

Epic fail. Come on w3C people as well as HTML and CSS developers. There is no excuse for this after twenty years.

Failure 2 – All floats

<!DOCTYPE html>
<html>
<head>
<title>html fails at layout</title>
</head>
<body style="margin: 0; padding: 0;">
<div style="width: 100%;height: 100px;background: gray;margin: 0;padding: 0;">
    <div style="width: 800px;margin: 0 auto;height: 100%;">
        <div style="width: 25%;height: 90%;float: left;background: lightblue;"><div style="background: blue;color: white;margin: 10px;height: 80%;float: left;">left</div></div>
        <div style="width: 50%;height: 90%; background: orange;float:left;"><div style="margin: 10px;height: 80%;"><div style="width: 25%;background: blue;color: white;height: 100%;float: left; position: relative; right: -50%; margin: 0px auto;text-align: center;">middle</div></div></div>
        <div style="width: 25%;height: 90%;float: right;background: lightblue;text-align: right;"><div style="background: blue;color: white;margin: 10px;height: 80%;text-align: right;float:right;">right</div></div>
    </div>
</div>
</body>
</html>

This almost looks right, but wait. How do we actually get it centered? Notice it isn’t centered. It is right of center.

left

right

middle

I can make it left of center, but I have to put the middle after the right and that is a hack:

left
right
middle

But I can’t make it centered. This is not a solution.

Failure 3 – Middle doesn’t float

So what if just the middle element doesn’t float?

<!DOCTYPE html>
<html>
<head>
<title>html fails at layout</title>
</head>
<body style="margin: 0; padding: 0;">
<div style="width: 100%;height: 100px;background: gray;margin: 0;padding: 0;">
    <div style="width: 800px;margin: 0 auto;height: 100%;">
        <div style="width: 25%;height: 90%;float: left;background: lightblue;">
            <div style="background: blue;color: white;margin: 10px;height: 80%;float: left;">left</div>
        </div>
        <div style="width: 50%;height: 90%; background: orange;margin: 0 auto;">
            <div style="margin: 10px;height: 80%;">
                <div style="width: 25%;background: blue;color: white;height: 100%; margin: 0px auto;text-align: center;">middle</div>
            </div>
        </div>
        <div style="width: 25%;height: 90%;float: right;background: lightblue;text-align: right;">
            <div style="background: blue;color: white;margin: 10px;height: 80%;text-align: right;float: right;">right</div>
        </div>
    </div>
</div>
</body>
</html>

That looks horrible.

left

middle

right

Now I have two problems:

  1. The right side is down below my banner.
  2. The top margin of center is applying above the banner, not inside it.

Finally – Success with middle doesn’t float and extra div elements

Well, the final html looks horrible and the center ends up being wrapped in four divs.

To center, you use width: 99%; margin: 0 auto” where the width has to be less than 100%. How is that intuitive. It isn’t. It is horrible. Come on W3C, how hard would it be to add proper intuitive alignment to the html and css spec?

<!DOCTYPE html>
<html>
    <head>
        <title>html fails at layout</title>
    </head>
    <body style="margin: 0; padding: 0;">
        <div style="width: 100%;height: 100px;background: gray;margin: 0;padding: 0px;">
            <div style="width: 800px;margin: 0 auto;height: 100%;">
                <div style="width: 25%;height: 90%;float: left;background: lightblue;">
                    <div style="background: blue;color: white;margin: 10px;height: 80%;float: left;">left</div>
                </div>
                <div style="width: 25%;height: 90%;float: right;background: lightblue;text-align: right;">
                    <div style="background: blue;color: white;margin: 10px;height: 80%;text-align: right;float: right;">Right</div>
                </div>
                <div style="width: 50%;margin: 0 auto;height: 80%; background: orange;padding-top:10px">
                    <div style="text-align:center;width: 90%; margin: 0 auto; background: blue;color: white; height: 80%;">Center</div>
                </div>
            </div>
        </div>
    </body>
</html>

The result is finally acceptable.

left

Right

Center

Let’s add some content to make sure:

Rhyous
top

Follow Us on FacebookFollow Us on Google+Follow Us on TwitterFollow Us on LinkedInFollow Us on RSS
Your Awesome Page Title


cube

Rant on html, css, and W3C

I get that you are trying to do new things with HTML5, but until you actually draw the common layouts, such as two column fixed, three column fixed, and two column liquid, and three column liquid, and actually define the spec to layout properly, it will never work.

Also, without over-wrapping div in div in div, you can’t make html work. That is why all the html and css for the examples on the web look so horrible, because they have to be to work around the terrible job done with html and css layouts.

Layout failures starting with the W3C provided specs are the primary reason why HTML is not the answer for business. I could have written a separate UI for a banner in every platform Android, iOS, Windows, Windows Phone, and Linux, all in less than the time it took me to hack around and figure out what needed to be done in html.

How to populate MailTo link with a form action using Javascript

Someday you might want to have a form where the submit button goes to a MailTo: link. You might want to populate the email’s To: Subject: and Body.

Here is a plunk to do it:
http://plnkr.co/edit/HWkMHhlaN5MO82wQfa0q

Here is the html and javascript:

<html>
<head>
<script>
function sendemail()
{
    var body = "First name: " + document.getElementById("fn").value + "\n";
    body +=  "Last name: " + document.getElementById("ln").value;
    var email = document.getElementById("email").value;
    var location = "mailto:" + email + "?subject=Hello world&body=" + encodeURIComponent(body);
    window.location.href = location;
}
</script>
</head>
<body>
<form action="javascript: sendemail()">
First name:<br>
<input id="fn" type="text" name="firstname">
<br>
Last name:<br>
<input id="ln" type="text" name="lastname">
<br>
Email:<br>
<input id="email" type="text" name="email">
<input type="submit" value="Submit">
</form>
</body>

How to add a progress bar to your blog

Some authors want to add progress bars to their blog. However, most authors are not web designers or developers. So they don’t know how to do this. Well, there is a secret in the html development world. The secret is that “Everything is easy once you know how to do it.” Yes, it is actually pretty easy to add a progress bar. I just added a progress bar to my blog.

Creating a Progress Bar on your Blog

Step 1. Create an HTML Widget for your side bar.

Using your blogging engine (WordPress or Blogger or whatever) create an html widget. In WordPress you would use a Text widget.

Step 2. Paste in the following html code

1st draft of Book 2
<div id="progressbar" style="background-color:black;border-radius:6px;padding:3px;">
    <div style="background-color:#dd6013;width:30%;height:10px;border-radius:4px;"></div>
</div>

It will look like this:

1st draft of Book 2

[Read More . . .]

Select Option Web Control with Knockout.js and MVVM

<!-- Step 1 - Create the HTML File or the View -->
<!DOCTYPE html>
<html>
<head>
    <!-- Step 2 - Include jquery and knockout -->
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
    <script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
     
    <!-- Step 3 - Add script to run when page loads -->
    <script type="text/javascript" >
        $(document).ready(function(){
 
 
            <!-- Step 4 - Create a data model -->
            var SelectableListDataModel = function () {
                // Private
                var _self = this;

                // Public
                _self.labels = new Array(); // Should have same count as values
                _self.values = new Array(); // Should have same count as Labels
                _self.defaultValue = 0;
                _self.canSelectMethod = function () { return true; },
                _self.push = function (label, value) {
                    _self.labels.push(label);
                    _self.values.push(value);
                };
            };
 
            <!-- Step 5 - Add an OptionViewModel -->
            var OptionViewModel = function(parent, label, value, canSelectMethod) {
                // private
                var _self = this;
                var _parent = parent;

                // public
                _self.id = ko.observable();
                _self.class = ko.observable();
                _self.label = label ? ko.observable(label) : ko.observable();
                _self.value = value ? ko.observable(value) : ko.observable();
                _self.isSelected = ko.computed(function () {
                    return (_parent && _parent.selectedValue) ? _parent.selectedValue() == _self.value() : false;
                }, _self);
                _self.canSelect = canSelectMethod ? ko.computed(canSelectMethod) : ko.computed(function () { return true; });
            };

            <!-- Step 6 - Add an SelectViewModel -->
            var SelectViewModel = function (selectableListDataModel) {
                // private
                var _self = this;
                var _defaultDataModel = new SelectableListDataModel();
                var _dataModel = selectableListDataModel ? selectableListDataModel : _defaultDataModel;

                // Public
                _self.canSelect = (_dataModel.canSelectMethod)? ko.computed(_dataModel.canSelectMethod) : ko.computed(_defaultDataModel.canSelectMethod);
                _self.list = ko.observableArray();
                _self.selectedValue = _dataModel.defaultValue ? ko.observable(_dataModel.defaultValue) : ko.observable();
                
                if (_dataModel.labels && _dataModel.values) {
                    for (var i = 0; i < _dataModel.labels.length; i++) {
                        _self.list.push(new OptionViewModel(_self, _dataModel.labels[i], _dataModel.values[i], _self.canSelect));
                    }
                }
                
                _self.selectedIndex = ko.computed(function () {
                    var index = 0;
                    var foundIndex = -1;
                    ko.utils.arrayForEach(_self.list(), function (item) {
                        if (_self.selectedValue() == item.value()) {
                            foundIndex = index;
                        }
                        index++;
                    });
                    return foundIndex;
                }, _self);

                _self.selectedText = ko.computed(function () {
               _self.selectedText = ko.computed(function () {
                    var index = _self.selectedIndex();
                    return (_self.list()[index]) ? _self.list()[index].label() : "";
                }, _self);
                }, _self);
                
                _self.clear = function (value) {
                    _self.selectedValue(value ? value : "");
                };
            }
 
            <!-- Step 7 - Create ViewModel for whatever you need -->
            function SurveyAnswerViewModel() {
                var self = this;
                 
                <!-- Step 8 - Create an observable list instance -->
                self.dataModel = new SelectableListDataModel();
                self.dataModel.labels = new Array("Good", "Average", "Poor");
                self.dataModel.values = new Array(10,5,1);
                self.dataModel.selectedValue = 10;
                
                <!-- Step 9 - Create a SelectViewModel instance -->
                self.selectGroup1 = new SelectViewModel(self.dataModel);                       
                 
                <!-- Step 10 - Create a computed value to require a selection before submitting -->
                self.canClick = ko.computed( function() {
                    return self.selectGroup1.selectedValue() != "";
                }, self);
                
                <!-- Step 11 - Make some button methods for this example -->
                self.submitClick = function(){
                    // Do something here
                }
                
                self.resetClick = function(){
                    self.selectGroup1.clear();
                }
            }
            
            <!-- Step 12 - Create a computed value to require a selection before submitting -->   
            ko.applyBindings(new SurveyAnswerViewModel());
        });
    </script>
</head>
<body>
    <!-- Step 13 - Create a drop down select item -->
    <select data-bind="options: selectGroup1.list, optionsText: 'label', optionsValue: 'value', value: selectGroup1.selectedValue"></select>
    <br />
    
    <!-- Step 14 - Add html elements to see other properties -->
    <p data-bind="text: 'Index: ' +  selectGroup1.selectedIndex()"></p>
    <p data-bind="text: 'Value: ' +  selectGroup1.selectedValue()"></p>
    <p data-bind="text: 'Text: ' +  selectGroup1.selectedText()"></p>
     
    <!-- Step 15 - Add a button and bind its to methods -->
    <button type="submit" id="btnSubmit" data-bind="enable: canClick, click: submitClick">Submit</button>
    <button type="reset" id="btnReset" data-bind="enable: canClick, click: resetClick">Reset</button>
 
</body>
</html>

Using slideToggle with Knockout’s MVVM

I recommend you use the third option: Option 3 – Boolean binding using a custom binding handler called slideToggle

See it live here: http://plnkr.co/edit/1YGchAyjkNSjYzmXFfK2

<!-- Step 1a - Create the HTML File or the View -->
<!DOCTYPE html>
<html>
<head>
    <!-- Step 2 - Include jquery and knockout -->
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
    <script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
     
    <!-- Step 3 - Add script to run when page loads -->
    <script type="text/javascript">
        $(document).ready(function(){
         
            <!-- Step 4 - Create a ViewModel -->           
            function viewModel() {
                _self = this;
                _self.showHideChild = function(viewModel, event) {
                    $(event.currentTarget).children('div').slideToggle()
                };
                _self.showHideNextSibling = function(viewModel, event) {
                    var siblings = $(event.currentTarget).siblings('div');
                    for (var i=0;i<siblings.length;i++) {
                        if (siblings[i].previousElementSibling == event.currentTarget ) {
                            $(siblings[i]).slideToggle();
                        }
                    }                 
                };
                _self.isVisible = ko.observable(false);
                _self.showHide = function() {
                    _self.isVisible(!_self.isVisible());
                }
            };
           
            ko.bindingHandlers.slideToggle = {
                init: function (element, valueAccessor) {
                    var value = valueAccessor();
                    $(element).toggle(ko.utils.unwrapObservable(value));
                },
                update: function (element, valueAccessor) {
                    var value = valueAccessor();
                    var isVisible = element.offsetWidth > 0 && element.offsetHeight > 0;
                    if (ko.utils.unwrapObservable(value) != isVisible) {
                        $(element).slideToggle();
                    }
                }
            };
           
            <!-- Step 5 -  Activates knockout.js bindings -->
          ko.applyBindings(new viewModel());
        });
    </script>
</head>
<!-- Step 4 - Create a HTML Elements with bindings -->
<body style="">
    <div>
        Option 1 - Child div
        <div id="child1" data-bind="click: showHideChild" style="border:2px solid;">
        Click me
            <div id="child2" style="display: none;">
              Now you see me!
            </div>
        </div>
        
        Option 2 - Siblings div
        <div id="sib1" style="border:2px solid;">
            <div id="sib2" data-bind="click: showHideNextSibling" >
            Click me
            </div>
            <div id="sib3" style="display: none;">
            Now you see me!
            </div>
            <div id="sib4">
            You should always see me.
            </div>
        </div>
        Option 3 - Boolean binding using a custom binding handler called slideToggle 
        <div id="bool1" style="border:2px solid;">
            <div id="bool2" data-bind="click: showHide" >
            Click me
            </div>
            <div id="bool3" data-bind="slideToggle: isVisible">
            Now you see me!
            </div>
        </div>
    </div>
</body>
</html>

HTML Search using MVVM with knockout.js

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
    <script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
     
    <script type="text/javascript" >
        $(function(){
         
            // custom binding handler so pressing enter in a textbox is the same
            // as clicking the button.
            ko.bindingHandlers.enterKey = {
                init: function(element, valueAccessor, allBindings, vm) {
                    ko.utils.registerEventHandler(element, "keyup", function(event) {
                        if (event.keyCode === 13) {
                            ko.utils.triggerEvent(element, "change");
                            valueAccessor().call(vm, vm);
                        }                        
                        return true;
                    });
                }         
            };
         
            var fakeSearch = function(args, callback) {
                var data = args;
                callback(data);
                return args;
            };

            var ButtonViewModel = function(text, searchMethod, canSearchMethod) {
                var _self = this;
                _self._canSearchMethod = canSearchMethod;
                _self.text = ko.observable(text);
                _self.onClick = searchMethod;
                _self.canClick = ko.computed(_self._canSearchMethod);                
            };

            var SearchParametersViewModel = {
                'SearchTerm': ko.observable(''),
                'SearchOption': ko.observable(''), // Not used in example
                'StartDate': ko.observable(''),    // Not used in example
                'EndDate': ko.observable('')       // Not used in example
            };

            var SearchViewModel = function(searchMethod, searchArgs) {
                // private properties
                var _self = this;
                _self._searchMethod = searchMethod;
                _self._searchArgs = searchArgs;
                _self._canSearch = function() {
                    return _self.searchParameters.SearchTerm() != null && _self.searchParameters.SearchTerm() != '';
                };

                // public properties
                _self.searchParameters = SearchParametersViewModel;

                _self.results = ko.observable('');
                
                _self.searchCallBack = function (data) {
                    _self.results(JSON.stringify(data));
                };

                _self.searchButton = new ButtonViewModel("Search", 
                function () {
                    _self._searchMethod(_self._searchArgs, _self.searchCallBack);
                }, _self._canSearch);
                
            };
           
          ko.applyBindings(new SearchViewModel(fakeSearch, {a: "1", b: "2"}));
        });
    </script>
</head>
<body>
    <input data-bind="value: searchParameters.SearchTerm, valueUpdate: 'afterkeydown', enterKey: searchButton.onClick" />
    <button type="button" id="btnSearch" data-bind="text: searchButton.text, enable: searchButton.canClick, click: searchButton.onClick"></button>
    <p data-bind="text: results"></p>
</body>
</html>

An HTML5 3 column layout example in ASP.NET

A while back I posted about an html5 three column layout. Here is the same layout, only this post has built the web site using ASP.NET and it includes a Visual Studio project.

The _Layout.cshtml file looks like this:

@RenderPage("~/Layout/_Header.cshtml")
@RenderPage("~/Layout/_Nav.cshtml")
<div id="main">
   <article id="main-article">@RenderBody()</article>
    @RenderPage("~/Layout/_LeftAside.cshtml")
    @RenderPage("~/Layout/_RightAside.cshtml")
</div>
@RenderPage("~/Layout/_Footer.cshtml")

Then of course, the HTLM5 layout is in the header, asides, article, and footer. And even though the Article is placed before the asides, the asides can be either on the left or the right.

Download it here: HTLM5_ASPNET_ThreeColumnLayoutExample.zip

Changing ol and li html tags to have “Steps” and Hanging indent.

Let’s say you want to have a list of items. However, you want the word “Step” before each number in the list. You may be tempted to not use the ol and li tags and just write the list.

Step 1 – Do something.
Step 2 – Do something else.

However, it will be obnoxious to type “Step” every time. The list doesn’t scale either. If the list gets long and you want to reorder the list, or even add a step, you have to change every number. Also, what if you want a hanging indent? How are you going to do that?

Well, just use these CSS classes.

ol.Steps {
  counter-reset: section;
  list-style-type: none;
  padding: 0;
  padding-left: 55px;
}

ol.Steps li {
  text-indent: -55px;
}

ol.Steps li:before {
  counter-increment: section;
  content: "Step " counter(section) " - "; // Change to ": " if you like
}

Here is some sample html:

<ol class="Steps">
  <li>The first thing to do.</li>
  <li>The second thing to do.</li>
  <li>The third thing to do. However, this step is really, really long. In fact, it is so long that the instructions to do this step wrap all the way into multiple lines.</li>
  <li>The fourth thing to do.</li>
</ol>

Here is how it looks:

  1. The first thing to do.
  2. The second thing to do.
  3. The third thing to do. However, this step is really, really long. In fact, it is so long that the instructions to do this step wrap all the way into multiple lines. No really. It has to go one multiple lines, even if the screen is really, really big.
  4. The fourth thing to do.

Using jQuery to enable/disable a button based on a text box

Since this is an html file, just create a blank file on your desktop called Test.html and copy and past the code below.

The steps for doing this are comments in the code.

Note: This should handle typing, pasting, code change, etc…

<!-- Step 1a - Create HTML File (see step 1b way below) -->
<!DOCTYPE html>
<html>
<head>
    <!-- Step 2 - Include jquery -->
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
 
    <!-- Step 3 - Add script to run when page loads -->
    <script  type="text/javascript">
        jQuery(document).ready(function () { 
            <!-- Step 4 - Bind method to text box -->    
            $("#txtField").bind("propertychange keyup input paste", setButtonState);
			
            <!-- Step 4 - Set the default state -->
			setButtonState();
        });
		var setButtonState = function () {
			if ($("#txtField").val() == "")
				$("#btnEnter").attr("disabled","disabled");
			else
				$("#btnEnter").removeAttr("disabled"); 
		}
    </script>
</head>
<body>
<!-- Step 1b - Add HTML elements --> 
<input type="text" id="txtField" size="50"/>
<button type="button" id="btnEnter">Enter</button>
</body>

Update: 5/22/2013: Fixed example. Before if it was used on a page with links, going forward and back could result in the button being disabled even if the text box was populated. This new example solves this issue.

See a MVVM version of this here:
Using MVVM with HTML5 and JavaScript

3 Column Table Layout verses 3 Column HTML5 Layout

Has HTML5 and CSS3 solved the layout problem? Or are tables layouts with CSS still a better solution.

You decide. Please post comments about other pros and cons you find. We all become experts when we all contribute.

Note: With both a table layout and an HTML5 layout, CSS is used, so this is not a CSS versus anything article. No matter which you use, lets agree that CSS should be used for style. However, CSS3 does add to the layout with the HTML5 solution.

3 Column HTML Table Layout with CSS Style

Click this link to see this layout: 3 Column HTML Table Layout with CSS Style

<!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">
<head>
<title>HTML Table Layout with CSS Style - 3 Column</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
 
html, body 
{
  height: 100%;
}
 
body 
{
    margin:0
}
 
table.layout 
{
  height:100%;
  width: 100%;
  border-collapse:collapse;
}
 
td.header 
{
  padding: 15px;
  height: 120px;
  color: white;
  background: black
}
 
td.nav-bar 
{
  padding: 15px;
  height:20px;
  background:DarkGrey;
}
 
td.leftcol 
{
  padding: 15px;
  width: 170px;
  min-width: 170px;
  background-color:Navy;
  color: white;
}

td.midcol 
{
  padding: 15px;
  min-width: 625px; /* Make 425px for min res of 800x600 */
}
 
td.rightcol 
{
  padding: 15px;
  width: 205px;
  min-width: 205px;
  background-color:Navy;
  color: white;
}
 
td.footer 
{
  height: 120px;
  background: DarkGrey;
  text-align: center;
}

</style>
</head>
<body>
<table class="layout">
	<tr>
		<td class="header" colspan="3">Header</td>
	</tr>
	<tr>
		<td class="nav-bar" colspan="3">Nav bar</td>
	</tr>
	<tr>
		<td class="leftcol">Aside left</td>
		<td class="midcol">Article</td>
		<td class="rightcol">Aside right</td>
	</tr>
	<tr>
		<td class="footer" colspan="3">
			<a href="http://validator.w3.org/check?uri=referer">
				<img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Strict" height="31" width="88" />
			</a>
		</td>
	</tr>
</table>
</body>
</html>

HTML Table Layout Pros

  • Validated with W3C
  • Only 95 lines of code with everything on its own line
  • Works with every browser according to BrowserShots.org
  • Very easy to use.
  • Making the table be 100% height is easy
  • Changing the width or height of any part of the page is easy

HTML Table Layout Cons

  • Layout is coupled to the HTML, layout would be best decoupled – Solved by using scripting languages like PHP and ASP.NET
  • Left column is found in HTML before the article body – No current solution

3 Column Layout HTML5 with CSS Layout/Style

Click this link to see this layout: 3 Column Layout HTML5 with CSS Layout/Style

<!DOCTYPE html>
<head>
<title>Layout HTML5 with CSS Layout/Style - 3 Column</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
 
html, body 
{
  height: 100%;
}

body 
{
    margin:0
}

header 
{
  padding: 15px;
  min-height: 150px;
  color: white;
  background: black
}
 
nav
{
  padding: 15px;
  min-height:20px;
  background:DarkGrey;
}

#main 
{ 
  /* height:100%; */ /* Broken with it, broken without it */               
  display: -moz-box;				/* Firefox */
  display: -webkit-box;				/* Safari and Chrome */	
  display: box; 					/* Future standard */
}

#main-aside-left
{
  padding: 15px;
  width: 170px;
  min-width: 170px;
  -moz-box-ordinal-group: 3; 		/* Firefox */
  -webkit-box-ordinal-group: 3; 	/* Safari and Chrome */
  box-ordinal-group: 3; 			/* Future standard */
  background-color:Navy;
  color: white;
}

article 
{ 
  padding: 15px;
  min-width: 625px;					/* Make 425px for min res of 800x600 */
  -moz-box-flex: 2; 				/* Firefox */
  -webkit-box-flex: 2; 				/* Safari and Chrome */
  box-flex: 2; 						/* Future standard */
  -moz-box-ordinal-group: 2; 		/* Firefox */
  -webkit-box-ordinal-group: 2; 	/* Safari and Chrome */
  box-ordinal-group: 2; 			/* Future standard */
}

#main-aside-right
{
  padding: 15px;
  width: 205px;
  min-width: 205px;
  -moz-box-ordinal-group: 1; 		/* Firefox */
  -webkit-box-ordinal-group: 1; 	/* Safari and Chrome */
  box-ordinal-group: 1; 			/* Future standard */
  background-color:Navy;
  color: white;
}

footer 
{
  height: 120px;
  height: 120px;
  background: DarkGrey;
  text-align: center;
}

</style>
</head>
<header>Header</header>
<nav>Nav bar</nav>
<div id="main">
   <article>Article</article>
   <aside id="main-aside-left">Aside left</aside>
   <aside id="main-aside-right">Aside right</aside>
</div>
<footer>
  <a href="http://validator.w3.org/check?uri=referer">
    <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Strict" height="31" width="88" />
  </a>
</footer>

HTML5 Layout Pros

  • W3C validated (experimental)
  • Article data comes before the data in the asides – This is a huge SEO bonus
  • Only 97 lines of code both CSS and HTML code, with everything on its own line
  • Very easy to use.
  • Making the table be 100% height is easy
  • Changing the width or height of any part of the page is easy

HTML5 Layout Cons

  • It doesn’t work on IE 9 or below and fails in many other browsers according to Browsershots.org. – No current solution.
  • Much of the CSS has to be duplicated – No current solution but when it is fixed, the code will be another 10 lines smaller
  • If the content does not fill the screen, there is no way to make the screen exactly 100% – No current solution but as long as the content is larger than the screen this doesn’t matter
  • Layout is coupled to CSS,  a styling tool, layout should be decoupled – Solved by having a separate CSS file just for layout

Conclusion

Use Table layouts for now if your browser support is high priority.

Use HTML5 layouts if you can enforce uses to use HTML5 capable browsers.

I demand a simpler CSS for HTML5!

Look, I love the browser as much as the next person, but that is as a user. I have no love for web development and the developers of html and css and the browsers are the reason why. Some things are not as hard as they are making it out to be.

HTML5 is becoming all the rage and the buzz world of the day. “Hey, just use HTML5 and all your problems will be solved.” Non-technical decision makers (and technical ones for that matter) are buying this. What nobody tells these people is that HTML5 is a current problem in and of itself. First, it is not a complete standard yet. Second, everyone is implementing the standard now, but doing it slightly differently. The problem is exacerbated by the use of vendor specific tags for future standards.

There are 13 known prefixes.

prefixorganization
-ms-, mso-Microsoft
-moz-Mozilla
-o-, -xv-Opera Software
-atsc-Advanced Television Standards Committee
-wap-The WAP Forum
-khtml-KDE
-webkit-Apple
prince-YesLogic
-ah-Antenna House
-hp-Hewlett Packard
-ro-Real Objects
-rim-Research In Motion
-tc-TallComponents

The design currently is the implement a feature first using a vendor tag and only later make it a standard feature. It is not possible to sustain this model for browser progress.

Could you imagine if there was a setting and every vendor implemented it with its prefix. For example, the display setting is already a problem and could get worse. What if it was as bad as this?

#main
{
  display: -ms-box;
  display: mso-box;
  display: -moz-box;
  display: -o-box;
  display: -xv-box;
  display: -atsc-box;
  display: -wap-box;
  display: -khtml-box;
  display: -webkit-box;
  display: prince-box;
  display: -ah-box;
  display: -hp-box;
  display: -ro-box;
  display: -rim-box;
  display: -tc-box;
}

Is it  possible that we may someday have to call a setting for each an every vendor prefix? Sure, but it is not likely. Ok, that above is a little absurd and an exageration, as nobody would use all those tags, we don’t even know what half those vendors are. However, even twice is too much! Do we really want to call a setting more than once? Should we ever have to? No, we shouldn’t. That is one of the biggest problems with web applications today.

I just can’t believe that we as developers are putting up with this html/css/browser problem.

I have to put the setting that is going to be the standard, and then for each browser, I have to put the browser specific setting. They are not smart enough to have each browser use the same tag for future standards, maybe something like -fs- for future standard, but instead lets use the vendor specific tag -moz- for mozilla and -webkit so we have to have a different tag for the same setting added for every browser we wish to support.

This is nonsense. I am so embarrassed for the organizations and their developers who have brought us to this point. We have to make every setting multiple times? Really? I am so glad I am not a developer for a browser because I take pride in my work and I would be so embarrassed to be part of such a mess.

How is it that browser developers aren’t smart enough to figure out a way we can use a single css tag, even for future standards?

Too many browsers

Competition is supposedly a good thing right? Well, I am not so sure that when dealing with free projects that is the case. I believe it is true for competitive businesses, but nobody is selling a browser.

Browsers are starting to sprawl worse than Linux. How many browsers do we rally need?

Here is a short list of browsers and they are all free:

  • IE 6, 7, 8, 9
  • Firefox
  • Chrome
  • Opera
  • Safari
  • Konqueror (KDE)

Sometimes with free projects, different from commercial projects, a division of the work force is a bad thing. I feel the same way about browsers as I do for Linux. If two groups worked together, they would often get more done than working apart. Sometimes there are natural divisions that lead to benefits in different areas, such as a desktop Linux version versus a server Linux version. With browsers there really isn’t a natural division like that.

We are re-inventing the wheel with each browser.

Unfortunately, control of the browser is coveted. The browser is the single most used application by the billions of computer users on our world. Controlling something as simple as the default browser homepage could mean the difference of millions, and perhaps billions, of dollars in advertising sales.

So to me, the question is this: How can we have a single browser but every commercial company still gets this “control” that they so desperately want?  Wow…once you really get the question pinned down, the answer is easy.

There is no reason that a single browser shouldn’t exist and all current browser developers could stop working on their browser and get one single browser to work. Use a BSD license so Windows and Apple and everyone else could include this browser with their own default settings (the default home page however they want, etc…), and mobile phones could do the same.

Then the next time the standard is increased from html5 to html6, we won’t have the mess we have now trying to go to html5. And we won’t have to wait as long because the combined efforts will take us to there so much faster.

Table Layouts still win over CSS layouts in 2012

The longer I am blogging and the more often I mess with my html layout (which is done in CSS) the more I come to realize that while CSS is a solution for HTML layouts but it is not a good solution and it has in my opinion completely failed to address the layout problem.

Look at any development language, GTK, QT, wxWidgets, Windows Forms, Windows Presentation Foundation, and a dozen others and they all have simple and easy to use layout systems. It is common to have Grid layouts, wrapping layouts, and more.

What does CSS2 and HTML4 have specifically for layout?

Nothing specific to layout. A div is not specific to layout. I was using what the author called Holy Grail 3 column liquid-layout. However, after two days, I still can’t change the width of my right side bar without breaking the layout in some way, which is mostly because the layers and layers of div elements is a mess in this layout.

What does CSS3 and HTML5 have specifically for layout?
They have new elements: article, aside, audio, bdo, canvas, command, datalist, details, embed, figcaption, figure, footer, header, hgroup, keygen, mark, meter, nav, output, progress, rp, rt, ruby, section, source, summary, time, video, wbr

However, while you can use HTML5 and CSS3, just be aware your website will only look good in newer browser. Please don’t try to view your site on Windows XP with IE7 or IE8.

I want the developers of Firefox, Opera, Internet Explorer, Safari, Chrome, HTML5 and CSS3 to know that when it comes to layout, YOU HAVE FAILED!!!!

If there is one reason that I wish Silverlight could become the de facto internet standard is for the simple reason that the layout features in XAML are so far superior than those of even the new HTML5 and CSS3 that there isn’t even a comparison.

So what is the solution to an easy HTML layout?

It just doesn’t get easier than the good old table layout, but you can at least style your layout with CSS.  CSS is good at styling even if it fails at layouts.

Look how easy it is:

<!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">
<head>
<title>3 Column Table Layout</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">

html, body {
  height: 100%;
}

body {
    margin:0
}

table.layout {
  height:100%;
  width: 100%;
  border-collapse:collapse;
}

tr.header {
  height:150px;
  background:black
}

tr.menu {
  height:50px;
  background:DarkGrey;
}

tr.body {
  height:100%;
}

tr.footer {
  height:150px;
  background:DarkGrey;
  height:150px;
}

td.leftcol {
  padding: 15px;
  width: 170px;
  min-width: 170px;
  background-color:Navy;
}

td.midcol {
  background-color:Grey;
  min-width: 625px; /* Make 425px for min res of 800x600 */
}

td.rightcol {
  padding: 15px;
  width: 205px;
  min-width: 205px;
  background-color:Navy;
}
</style>
</head>
<body>
<table class="layout">
<tr class="header">
<td colspan="3"></td>
</tr>
<tr class="menu">
<td colspan="3"></td>
</tr>
<tr class="body">
<td class="leftcol"></td>
<td class="midcol"></td>
<td class="rightcol"></td>
</tr>
<tr class="footer">
<td colspan="3">
  <p style="text-align: center;">
    <a href="http://validator.w3.org/check?uri=referer">
	  <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Strict" height="31" width="88" />
    </a>
  </p>
</td>
</tr>
</table>
</body>
</html>
  1. t took less than 30 minutes to make this layout.
  2. It still uses CSS to style the layout.
  3. Changes are easy (any column can be re-sized in seconds).
  4. Left and right columns are always the same height.
  5. The background colors always extend vertically as far as needed.
  6. It is of course, W3C compliant.

Sorry CSS, until you have a real layout solution I think you lose to a good old-fashioned table.

But what about dynamically changing the layout?

Well, lets face, it. Dynamic changes are done in code anyway, and any good developer can code up that solution. Besides, most web sites are using some sort of Content Management System, like WordPress, Drupal, SilverStripe, or others. Each of these allow for Themes or Styles and so you can easily code up a way to switch styles with code such as php, asp.net, ruby, or any programming language.

How to add a corner banner to your web page?

Today I noticed that a few sites, including WordPress.com have a corner banner on their pages to help alert others to a specific cause (in this case they are against SOPA & PIPA).

And so everyone can add a corner banner to their sites, I am going to post how to do it.

Step 1 – Create the image

There are dozens of ways to create the images and if you can create it yourself, just do so.

Note: While I for this cause WordPress would care if you used their image, I thought it best to make my own if for no other reason than to use my color style.

  1. Using your favorite image editor create a new image.
    Note: I am going to use the free Paint.NET program.
  2. Change the canvase size to be a square. Use a size between 150×150 to 200×200. I went with 175×175.
  3. Make the background transparent.
  4. Draw a line from corner 0,0 to corner 175,175.
    Note: In some applications, holding down shift while drawing your line will guarantee the line is a perfect 45 degree diagonal.
  5. Draw a second line from  60,0 to about 175,115.
    Note: Mine came out to 175,114, which is close enough.
  6. Fill the  area inside the lines as you desire.
    Note: I used a nice soft gradient.
  7.  In a new layer (also transparent), add text in a normal horizontal way.
  8. Rotate only the new layer 45 degrees. (-45.00 degree.)
  9. Show both layers.
  10. Move the text to the appropriate place in the image.
  11. Save as a png or jpg file.
  12. Upload the image to your site.

Here is my image. Feel free to download it and use it.

Stop Censorship

Step 2 – Change your web site code to display the image

  1. Add the following style to your css file.
    #right-corner {
    	position: fixed; /* Make sure you can align it exactly */
    	cursor: pointer; /* Change the cursor on mouse over */
    	top: 0px; /* Change to 100px to put it under a 100px banner */
    	right: 0px; /* Change to 100px to put it left of a 100px right-side bar */
    	z-index: 99999; /* make sure it is the top element always */
    }
    

    Note: If you do not have a css file, then go to step two and add this as well in step 2.

    <style>
    #right-corner {
    	position: fixed; /* Make sure you can align it exactly */
    	cursor: pointer; /* Change the cursor on mouse over */
    	top: 0px; /* Change to 100px to put it under a 100px banner */
    	right: 0px; /* Change to 100px to put it left of a 100px right-side bar */
    	z-index: 99999; /* make sure it is the top element always */
    }
    </style>
    
  2. Open whatever html or script file that create the top part of your web site.
    Note: Often it is a top.htm, header.htm, or something similar.
  3. Find your <body> tag and add a link to http://americancensorship.org anywhere inside the <body> tag.
  4. For the tag, set the “id” to the css id called right-corner.
  5. Put your image inside the link.The code should look as follows:
    <a id="right-corner" href="http://americancensorship.org/" target="_blank">
    	<img src="/wp-content/uploads/2012/01/Stop-Censorship.png" alt="Stop Censorship">
    </a>
    
  6. Save your changes.
  7. Refresh your page.

You now have a corner banner image on your page.


While I want to add a corner banner to my site and state that I am against SOPA and PIPA as well, here is my disclaimer:

I haven’t fully read the SOPA & PIPA document, so I am against it based on hearsay…but it is reliable hearsay. Also there may be statement in the document that I am for. Instead of telling you what I am against in the SOPA & PIPA document, it is easier just to write my thoughts.

  1. The U.S. Government should not censor the internet for the public in any way.
  2. The government should in no way tamper with or hinder the freedom of speech on the internet
  3. Certain organizations, such as parents at home, schools, or a business (except ISPs) may censor/filter the internet for their specific internet connection. (And hence anyone only using their internet access is also censored).
  4. The Government may censor the internet in locations they naturally control, such as in Government Buildings, military facilities, or government-paid-for schools.
  5. An ISP may provide an optional censorship/filtering service so long as it is not applied by default or when not specifically requested. If the ISPs whole business plan is based on the idea of a safe internet for families, such as MStar, then defaulting to enabling certain censorship/filtering service is allowed.
  6. Internet Registrars may enforce rules that make filtering easier, like having all porn sites end in .xxx or all gambling sites end in .gmb so they can easily be filtered, especially in homes, schools, and some work places.  But enforcement should be done by agreement of internet registrars and not really by the U.S. Government.
  7. The government should pursue theft of intellectual property the same on the internet as is does with theft of intellectual property off the internet with one stipulation: Only the most minimal part of a site should altered. For example, if a site posts a copyrighted movie, only the movie itself should be removed, every other part of the site should remain, including a broken link to the movie.

If the bill could be written with those few sentences, it would pass easily and I don’t think anyone would care.

CSS is a solution for HTML layouts but it is not a good solution

I don’t want to offend any CSS purists out there, but the more I use CSS the more I realize that is isn’t the best tool in the toolbox for layout. I am not saying html tags such as table layouts are better, but I am saying that there were problems that CSS was written to resolve, and as I understand it HTML layouts and page design is one of them, but even after 10 years it is nowhere near where it needs to be in a few areas:

  1. Feature set
  2. Simplicity
  3. Readability is low
  4. Ability to translate functionality into an IDE is poor (as seen by the fact that there is not good CSS IDE)

A while back I found a three column layout and posted about it: http://www.rhyous.com/2011/02/26/the-perfect-layout-for-a-three-column-blog/

At the time, I thought, great someone has figured out all the complexities for me. Well, actually no, they didn’t.  Trying to implement this for a blog design has been a nightmare because I want even more features and adding them to the design has not worked out very well. The design is great, and the author, Matthew James Taylor, should not think that I am trashing his work. No, not at all. He provided an excellent solution. No, instead, I am trashing CSS and its sub-par implementation.

How is it that after so many years and so many versions, CSS is overly complex and the “tricks” such as making  div elements embedded in div elements as Matthew James Taylor used, work but barely and they cause almost as many problems as they solve.

Now I have a problem trying to make the columns on the left and right have rounded corners.  Not going to happen. The way the nested div elements were used to make the background color go all the way down also seems to mean that four rounded corners in each column extending the lengthe of the screen is not likely to happen without more CSS tricks.

I need to add a menu bar, as this layout didn’t have one, but I need the menu bar to also have a drop down menu for submenu items.  However, the way this CSS layout used the div inside div trick, makes the drop down menu below the middle column so that is a problem.

Had I used a table to layout my site, it would be done already. Now, it wouldn’t be the most maintainable but it would be done.  However, maybe a programming language such as PHP or ASP.NET could be used to improve the maintainability.

So to all those who are participating in the CSS standards, please go back to the drawing board when it comes to the layout:

  1. It seems a sub-par job separating the design from the code.
  2. It seems a sub-par job providing an easy tool for laying out a website. You have left us with a tool that is not good enough!
  3. There are not any good IDEs for CSS and HTML (No, neither Dreamweaver or Expression Web are good for laying out web pages, but you know what, it isn’t the fault of the IDE!)

You did solve some of the easy parts quite well, most of the parts that are not “layout” but more just color schemes.

  1. Change font-size and color works great.
  2. Float something to the left, great.

However, a simple feature of “as tall as the page” or the idea of a few elements where all but one are fixed size and the one that isn’t stretches the width of the height of the screen doesn’t exist. It seems to be there for width, but not for height or else it is there but just too hard to get.  For example, look at the three column design.  The reason the author had to nest the div elements was to get the three column div elements to extend all the way to the bottom of the page.  Without this hack, when there are three columns (left, middle, right) normally each one is a different length.  Really, CSS hasn’t solved this with a simple solution, yet? Sorry to be critical, but after this long, it should be better.

Here is what I want it shouldn’t be so difficult.  These tags don’t exist, this is a hypothetical of what I want.  Funny that as I write this some is similar to WPF, which is far superior to CSS for layout design IMHO.

<div name="Header" width="stretch" height="100px"> .... </div>
<div name="Menu" width="stretch" height="sizetocontent> .. </div>
<div name="Columns" width="stretch">
    <Group type="Horizontal" width="stretch">
        <div name="LeftCol" width="250px" hight="stretch"> ... </div>
        <div name="MiddleColCol" width="stretch" hight="stretch" MinWidth="300"> ... </div>
        <div name="LeftCol" width="stretch" hight="stretch"> ... </div>
    </HorizontalGroup>
</div>
<div name="Header" width="stretch" height="100px"> .... </div>

First off, the readability of the above syntax is amazingly clear and simple (IMO) and one does not have to wonder what is intended.

So please, powers that be of CSS, lets start over. Yes, I am aware it could take a decade but it is worth it if this time, you get it right! Look at WPF, sure it is not exactly the same, but Microsoft invested a lot of time and money into Windows Forms and they still felt the need for a new solution in WPF and it has been around 6 years and still Windows Forms are around, but more an more everyone is moving to WPF. CSS should go the way of Windows Forms, and become the old solution that a better solution is designed to replace.

Here are some more articles where people agree that CSS needs to be replaced with a better tool.  Please note as you read these posts that I don’t think CSS sucks.  I think it was a descent tool written to solve a problem, and succeeded in some areas and failed in others, and now that we know what works and what doesn’t a new better tool should be developed that keeps what works in CSS bt also succeeds where CSS fails.

Ten reasons why CSS sucks « Greg’s Head

CSS Sucks (for layout) | Accidental Scientist (this is interesting because Layout is my main complaint)

Tables vs CSS: 15 points to consider when choosing (this one has a lot of links that are not in favor of CSS)

If you are a framer for a house, a hammer is better than a wrench for nailing nails.  But a nail-gun is better than a hammer. CSS is somewhere in between. Here is a good hammer/nail gun analogy to describe CSS. Once I had a nail gun but the air compressor wasn’t quite strong enough and didn’t send the nails all the way in. So I use the nail gun because this was still faster, and did all the nailing. Then I pulled out my hammer and to finish the job.  CSS is like a nail gun without enough air.  It is better than a hammer, but not as good as it could be.

Maybe CSS doesn’t need to go away, maybe it just needs to stop doing layout.  What if it just did size and color and decoration and a new tool integrated with HTML and CSS to do layouts. But maybe it is better to have one solution for design.