views:

556

answers:

9

For my html form, it seems that I'm unable to create cross browser hover and pressed states for <button>.

I really want this as it creates good user feedback (and a polished look and feel). With <a> it's easy to do, but it breaks accessibility rules.

What should I do?

As requested, an example:

<form name="contact" action="index.php" method="post">
    <ul>
        <li>
            <label for="name" class="name">Name</label>
            <input type="text" name="name" id="name" size="30" />
        </li>
        <li>
            <button type="submit" class="submit">Send</button>
            <input type="hidden" name="submit" value="yes">
        </li>
    </ul>
</form>

button.submit
{
    background:#F99;
    font-size:3em;
}

button.submit:hover /* white button with colored text */
{
    background:#FFF;
    color:#F99;
}
A: 

jQuery

mattRo55
Some specifics would be nice, but Charles beat you to that.
David Dorward
+1  A: 

Even if you can find a solution (those mentioned by Matt Ross could be one) you should better choose accessibility than polished look and feel !

Boris Guéry
So you're saying that: a) it probably can't be done? b) jQuery breaks accessibility?
Kriem
jQuery does not break accessibility, you just need to follow accessibility rules. When JS is used properly, it can actually aid in accessibility.
Redbeard 0x0A
No i said, it cannot probably done, but if you can do it (using jquery or anything else) be sure to don't break accessibility.I'm not saying jquery does, but just be carefull of what you do.Often people breaks accessibility, just to a nice looked gui, and i think you should better take in consideration accessibility than any nice effects to look good, but not usable.
Boris Guéry
It's an interesting discussion. I wonder if the real world works that way. People are used to seeing nice stuff and don't care about how it's done. I know it contradicts my question and in the end I agree with you. But I still wonder. :)
Kriem
+1  A: 

How about a jQuery solution, something like this:

$("input:button").mouseover(function(e) {
    $(this).addClass("hovered");
}).mouseout(function(e) {
    $(this).removeClass("hovered");
}).mousedown(function(e) {
    $(this).addClass("pressed");
}).mouseup(function(e) {
    $(this).removeClass("pressed");
});
Charles
I might not rush to use jQuery in particular, but using JavaScript to add and remove classes to and from the button is the way forward (if styling is that important).
David Dorward
I don't suggest this. Using JS for styling.
çağdaş
@cagdas, Charles does not suggest using JS for styling. He is using JS for behaviour (the onmouseovers) the styles will be defined in the classes. This is just the moest easy way to cross browser add hover and pressed styles.
Pim Jager
If the stylesheet also includes :hover and :active styles, then it will work for the better user agents when they have JS disabled too.
David Dorward
+2  A: 

I've not tested this extensively, and not yet cross-platform, but for both Midori and FF3.x (on Ubuntu 8.04) the button tags take styles for :hover,:focus and :active (similar to a tags).

This works, certainly:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
    <head>

    <title></title>

    <style type="text/css">

    button {color: #f00; 
     background-color: #ccc;
     border: 0 none transparent;}
    button:hover {color: #0f0; }
    button:active {color: #00f; }

    </style>

</head>

<body>

    <div id="wrapper">

    <form method="post" action="" enctype="form/multipart">

     <fieldset>
      <label for="input1">Label 1:</label>
      <input id="input1" name="input1" type="text" />

      <label for="input2">Label 2:</label>
      <input id="input2" name="input2" type="text" />
     </fieldset>

     <fieldset>

      <button class="reset" type="reset">Reset</button>
      <button class="submit" type="submit">Submit</button>

     </fieldset>

    </for>

    </div>

</body

</html>

Demonstration at: http://www.davidrhysthomas.co.uk/so/buttons.html

Further edited to respond to question-edit:

You could try adding a third list element, and naming them (I'd further recommend using fieldsets rather than lists, but let's go with what you've got).

<head>
<link rel="stylesheet" type="text/css" href="regularStylesheet.css" />

    <!--[if ie lte7]>
<link rel="stylesheet" type="text/css" href="ie-adaptations.css" />
    <![endif]-->

<form name="contact" action="index.php" method="post">
    <ul>
        <li>
            <label for="name" class="name">Name</label>
            <input type="text" name="name" id="name" size="30" />
        </li>
        <li class="submit-buttons">
            <button type="submit" class="submit">Send</button>
            <input type="hidden" name="submit" value="yes">
        </li>
        <li class="submit-links">
            <a href="where/ever/you/send.html">Send</a>
            <input type="hidden" name="submit" value="yes">
        </li>
    </ul>
</form>

Then in the regular CSS add:

li.submit-buttons
{
    display: block;
}

li.submit-links
{
    display: none;
}

And reverse that in the IE-adaptations.css:

li.submit-buttons
{
    display: none;
}

li.submit-links
{
    display: block;
}

It's not perfect by any means, but it doesn't upset devices using forms-mode and should allow the buttons to show; and should only force IE 7 (and below) to display the links. So...hopefully shouldn't upset accessibility too much.

David Thomas
Yes, but Kriem specifically mentioned wanting a cross-browser implementation.
Charles
Well, I can't check cross-platform, but the above certainly works cross-browser for Opera (9.x), FF 3.x and Midori (0.0.17, for the Webkit engine). If, on the other hand, 'cross-browser' was used as a shorthand for 'in IE' then...I'm not much help, since I don't own any MS platforms anymore. Sorry... =/
David Thomas
My above comment wasn't *intended* as a flame-bait/flame-war, just perhaps an overly-concise summary of my inability to aid much for IE-related issues, for which I am genuinely sorry.
David Thomas
You don't have IE even for dev purposes?
annakata
I mess about with html/php et al as a hobbyist pursuit, if I were pro then I'd have to have an MS install, but...as I only support my own network/intranet I've gone with FOSS solutions which are mostly standards-compliant.
David Thomas
Grant Wagner
Thanks for the links Grant =)
David Thomas
+11  A: 

The pattern I see myself do over and over with accessibility is to start with what's accessible to everyone and replace it on the client-side with the preferred solution. Then if they don't have that technology, it degrades gracefully. Specifically we're talking about javascript here.

For instance, start by using a normal button in your form. This will work for everyone, regardless of whether or not they have javascript enabled. Then use javascript to replace that button with an anchor tag (so you can use :hover in your css), or simply use javascript to perform the hover effect you want (if you're using jQuery, you can bind an event to the button's mouseover).

This means the small subset of people who don't have javascript enabled and aren't using a browser that supports more advanced :hover usage won't see your hover effect, but you'll ensure that it always degrades gracefully.

Jon Smock
+1 "Progressive Enhancement".
anonymous coward
When in "forms mode", screen readers ignore links. If you replace the submit button with a link (even one that uses JS to submit the form), then it will be invisible to screen reader users when in forms mode.
David Dorward
+3  A: 

Internet Explorer 6 only supports the :hover CSS attributes for anchors .

If you are supporting IE6, you will need to use some javascript solution like @charles suggested, basically you need to dynamically add/remove classes to the element. I usually put these 'fixes' in an IE6.js file with conditional comments.

Using jQuery is optional, but it really helps cut down the amount of javascript you have to write to achieve these effects.

Redbeard 0x0A
+1  A: 

I might be putting my foot in my mouth or something here, but I just wanted to point out something else to consider. However you decide to solve this problem, if your button or anchor is supposed to perform some action (like delete a record or change your bank account) then I strongly suggest you make sure you are performing a postback (POST). This is what a button normally does in a form. Do not perform a GET, which is what an achor usually does.

This is because GETs are too easily followed by accident by things like search engines, browser pre-cachers, and other stuff. Where as a POST is recognized as something that performs an action and isn't followed automaticly.

On the other hand if your "button" is just doing a query of some sort then a GET is just fine.

And you can do a post with an anchor also, especially with javascript.

someone with this fresher on their mind can probalby fill in a bunchof the details that I glossed over.

Zack
+2  A: 

Using javascript you could also replace the button with the a-tag as Jon suggests. This is using jQuery but you could do this with just normal javascript or any other library:

 var ahtml = "<div class='button'><a href=#>blabla</a></div>"; //whatever the HTML is for the styled a tag
 $('button.submit') //select button
    .hide()//Hide the button
    .after(ahtml) //insert the styled a html
    .next() //find the inserted html
       .click( function(e) { //add click behaviour to the inserted HTML
         $(this).prev().click(); //trigger click event of submit button
         return false; //stop both event bubbling and event triggering
       });

This way you have the button, for people without javascript. And also have a nice styled a tag for people with javascript.

Pim Jager
+1  A: 

You can definitely do this with CSS alone (and a little js for poor ie6).

First, make it work in FF with :hover, :active, whatever. then add some js to add classes to the buttons on hover, click.... Add these classes to your :hover, :active... declarations (button:hover, button.hover{color:red}) and off you go. You'll need to do some massaging for safari and the IEs but it can absolutely be done.

Another possibility is a sort of mashup of the previous suggestions. If I'm not mistaken, JAWS will read elements with visibility:hidden (not sure about window eyes). Instead of removing the button with js or setting it display:none, setting it to invisible should work cross user agent. Then just us JS to bind the link click to the form submit.

Will Moore