Agenda
HTML5 and CSS3 features give us great opportunity to create rich animated user interfaces comparable with desktop versions. Here I will explain how to create rich UI button with custom HTML content and CSS3 tools only, without using javascript and images.
I am not going to explain details of an appropriate CSS3 style, but a live demo will be attached to every step, so you will be able to see how it affects different browsers.
Layout
Let's specify a general .button
class, with some default styles. The class will be suitable for different kinds of tags to make them look like rich UI button.
.button { border: none; outline: none; text-decoration: none; display: inline-block; padding: 10px; margin: 10px; font-size: 2em; color: black; background-color: lightgray; cursor: pointer; }
And apply this class to an anchor:
Button
So our new button will look and behave like: Button
Looks ugly, but let's go on:)
Transform effect on :active selector
Let's set a transform effect on button's :active selector to decrease button size on mouse down:
.button:active { transform: scale(0.9, 0.9); -o-transform: scale(0.9, 0.9); -ms-transform: scale(0.9, 0.9); -moz-transform: scale(0.9, 0.9); -webkit-transform: scale(0.9, 0.9); }
So here it is: Button
But there is an issue with css transform for content elements. It's described in details here: StackOverflow - Non-clickable area on transforming anchor. Shortly, there is an area that doesn't raise a click on the border of content of the button.
If we select the content, we can see the border, specified on the picture:
The area is very small, but it can be very annoying to your user when once in a while he clicks the button and nothing happens.
To fix the issue, we should override clickable area by some streched stub which will intercept the :active
state from the whole button area. To avoid inserting additional markup it can be reached by :before
selector:
.button { position: relative; } .button:before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 1; }
New button without non-clickable area: Button
Disallow button's content selection
In some cases it's not even needed, but considering that you cannot select content on a normal button, we should do it:
.button { user-select: none; -o-user-select: none; -ms-user-select: none; -moz-user-select: none; -webkit-user-select: none; }
You cannot select the content by dragging the mouse: Button
Background color transition effects
To make the button smoothly change its background on mouse hover:
.button { transition: background 0.3s ease; -o-transition: background 0.3s ease; -ms-transition: background 0.3s ease; -moz-transition: background 0.3s ease; -webkit-transition: background 0.3s ease; } .button:hover { background-color: darkgray; } .button:active { background-color: gray; }
Looks more sexy:) Button
Actually you can add even more transition effects for other styles, or customize transitions for different states.
Reset predefined appearance
Browsers can have predefined appearance while rendering html elements. Since we are going to apply the .button
class to different kinds of tags, and to control the element states ourselves, we should do it to prevent unpredictable behavior:
.button { appearance: none; -o-appearance: none; -ms-appearance: none; -moz-appearance: none; -webkit-appearance: none; }
There are 2 plain <button>
elements, which may look different in different browsers, the second one resets its appearance:
Shadow effects
There is a simple outer shadow effect, which makes it 3D feel:
.button { box-shadow: 3px 3px 3px #888888; -o-box-shadow: 3px 3px 3px #888888; -moz-box-shadow: 3px 3px 3px #888888; -webkit-box-shadow: 3px 3px 3px #888888; } .button:active { box-shadow: none; -o-box-shadow: none; -moz-box-shadow: none; -webkit-box-shadow: none; }
And the button: Button
I also like inset shadow, which looks pretty attractive:
.button { box-shadow: 0px 0px 6px 3px #888888 inset; -o-box-shadow: 0px 0px 6px 3px #888888 inset; -moz-box-shadow: 0px 0px 6px 3px #888888 inset; -webkit-box-shadow: 0px 0px 6px 3px #888888 inset; } .button:active { box-shadow: 0px 0px 2px 2px #888888 inset; -o-box-shadow: 0px 0px 2px 2px #888888 inset; -moz-box-shadow: 0px 0px 2px 2px #888888 inset; -webkit-box-shadow: 0px 0px 2px 2px #888888 inset; }
Border radius
Just very simple rounded border:
.button { border-radius: 5px; -o-border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; }
The buttons with border radius:
Button
Button
Gradients
Linear gradient to make it a salient feel. The issue is that gradient transitions are not supported, so we make a trick with background-position
style:
.button { background-image: linear-gradient(lightgray 0%, gray 50%, lightgray 100%); background-image: -o-linear-gradient(lightgray 0%, gray 50%, lightgray 100%); background-image: -moz-linear-gradient(lightgray 0%, gray 50%, lightgray 100%); background-image: -webkit-linear-gradient(lightgray 0%, gray 50%, lightgray 100%); } .button:hover { background-position: 0 28px; } .button:active { background-image: linear-gradient(gray 0%, lightgray 50%, gray 100%); background-image: -o-linear-gradient(gray 0%, lightgray 50%, gray 100%); background-image: -moz-linear-gradient(gray 0%, lightgray 50%, gray 100%); background-image: -webkit-linear-gradient(gray 0%, lightgray 50%, gray 100%); }
The buttons with gradients:
Button
Button
Summarized styles
.button { border: none; outline: none; text-decoration: none; display: inline-block; padding: 10px; margin: 10px; font-size: 2em; color: black; background-color: lightgray; cursor: pointer; position: relative; user-select: none; -o-user-select: none; -ms-user-select: none; -moz-user-select: none; -webkit-user-select: none; transition: background 0.3s ease; -o-transition: background 0.3s ease; -ms-transition: background 0.3s ease; -moz-transition: background 0.3s ease; -webkit-transition: background 0.3s ease; appearance: none; -o-appearance: none; -ms-appearance: none; -moz-appearance: none; -webkit-appearance: none; box-shadow: 3px 3px 3px #888888; -o-box-shadow: 3px 3px 3px #888888; -moz-box-shadow: 3px 3px 3px #888888; -webkit-box-shadow: 3px 3px 6px #888888; border-radius: 5px; -o-border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; background-image: linear-gradient(lightgray 0%, gray 50%, lightgray 100%); background-image: -o-linear-gradient(lightgray 0%, gray 50%, lightgray 100%); background-image: -moz-linear-gradient(lightgray 0%, gray 50%, lightgray 100%); background-image: -webkit-linear-gradient(lightgray 0%, gray 50%, lightgray 100%); } .button:before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 1; } .button:hover { background-color: darkgray; background-position: 0 28px; } .button:active { transform: scale(0.9, 0.9); -o-transform: scale(0.9, 0.9); -ms-transform: scale(0.9, 0.9); -moz-transform: scale(0.9, 0.9); -webkit-transform: scale(0.9, 0.9); background-color: gray; box-shadow: none; -o-box-shadow: none; -moz-box-shadow: none; -webkit-box-shadow: none; background-image: linear-gradient(gray 0%, lightgray 50%, gray 100%); background-image: -o-linear-gradient(gray 0%, lightgray 50%, gray 100%); background-image: -moz-linear-gradient(gray 0%, lightgray 50%, gray 100%); background-image: -webkit-linear-gradient(gray 0%, lightgray 50%, gray 100%); }
And how different kind of elements look:
<a>
: Anchor
<button>
:
<input type="button">
:
<button>
with custom content:
Browsers compatibility
As the article is about HTML5 and CSS3, it basically works in all desktop browsers which support these technologies. I can enumerate what I have tested:
IE8 and earlier - no support. I believe people who use IE8 should not expect the best browsing experience. Therefore I didn't write -ms-filter
styles as it's not about CSS3.
IE9 - user-select
doesn't work. It also doesn't support appearance
, transitions and gradients. But gradients can be reached by IE filter
property.
IE10 - it doesn't support appearance
and user-select
. Even though it supports -ms-user-select
property, but it doesn't seem to be working. We should probably wait for SP1;)
Opera (12.10) - user-select
and appearance
doesn't work. But it's possible to prevent content selection by using unselectable="on"
inline attribute.
Mozilla Firefox (19.0.2) - everything seems to be working.
Google Chrome (25.0.1364.172 m) and Safari (5.1.7) - everything is supported.
Mobile browsers - still need to be investigated.
Post Scriptum
Fell free to use this code in your projects. I'm sure designers can create more attractive styles, and this can be a start point for them. I wish I had some designer skills, but I don't;)
I also appreciate any constructive criticism, so please comment if you see any mistake or inaccuracy here.
No comments:
Post a Comment