CSS For Sliding Door Input Buttons In Rails
Tuesday, February 26th, 2008UPDATE: This article appears to get a reasonable amount of traffic from google so I figured I’d update/correct it. The solution I outline below ended up not working as nicely as I had hoped, so I scrapped it. Instead, I just created a single image and making all my button text fit within the length of that single image. Sliding doors isn’t worth the trouble (i.m.h.o), and what I wrote below isn’t a perfect solution anyway.
——
This is one of those annoying things that took me all day to figure out, and the stuff I was able to find on the internets wasn’t very helpful….
I wanted to create some fancy looking buttons with curved corners. But I wanted them to be real buttons (http:post) , not links (http:get) that just look like buttons.
I looked for a way to do it and found a way to do it using links and a way to do it using the <button> element. Neither of these did what I wanted. Rails uses <input type=”button” /> rather than <button>. After learning more about the difference between buttons and inputs I’m still not sure why, but I figured there must be a good reason. I did try <button> but IE was giving me headaches (I couldn’t click on the button) so I gave up. I tried adapting these methods and they weren’t working for me.
One of the methods linked above worked briefly, but it required floating one of the elements left, which makes layout a REAL pain!
So, I (perhaps by accident) found an easier way. I took the opposite approach from using the outer html element for the left image.
First, I made my own button helpers like so:
module ButtonHelper
def fancy_button_to(button_text, action_text, button_class = "button")
return '<form method="post" action="' + action_text + '">' + button_base(button_class, button_text) + '</form>'
end
def button(button_text, button_class = "button")
return button_base("button", button_text)
end
protected
def button_base(button_class, button_text)
return '<p class="button_wrapper"><span class="' + button_class + '"><input value="' + button_text + '" type="submit" /></span>'
end
end
Then, the css looks like this:
span.button input {
border:0;
cursor:pointer;
white-space:nowrap;
color: #fff;
text-align:center;
font-weight: bold;
}
span.button {
background: transparent url(/images/small_button_left.gif) no-repeat top left;
padding: 6px 0px 6px 5px;
}
span.button input{
background: transparent url(/images/small_button_right.png) no-repeat top right;
padding-right: 5px;
font-size: 15px;
height: 25px;
}
You will need to create some sliding door images (see links at the beginning of this post). The values measured in pixels in the css will depend on those images.
Of course, there is some conditional css, but it’s pretty short. You just have to use different padding amounts for IE6 and IE7. So, I created a new css file call button_ie.css. I conditionally include it in the html file like so:
<!--[if lte IE 7]> <link href="/stylesheets/button_ie.css" media="screen" rel="Stylesheet" type="text/css"></link> <![endif]-->
The button_ie.css looks like this:
span.button {
padding: 0px 0px 0px 5px;
}
This isn’t perfect. Occasionally there is an error of 1 pixel in firefox 2, but IE6, IE7, & Safari seem to work fine.
Hopefully this will save someone else the frustration I faced today. Though to be honest, I’m actually thinking of moving to fix width buttons.





