A month ago I was creating the todos demo of Racer, and I got distracted with styling HTML form elements in CSS. I managed to hack together full styling of every common input type that is compatible with all current browsers and released the code as Impress. Impress requires adding extra HTML elements in some cases, but as far as I can tell, it is the only complete set of HTML form styles that doesn't rely on any JavaScript. Eventually I will parameterize the styles to make them easier to customize, but right now I am mostly working on Derby's templating engine.
In getting Impress to work across all browsers, I discovered some really interesting CSS hacks. The most interesting of them is perhaps the elusive CSS border gradient. While CSS3 provides the border-image property, this property is really designed for repeated image borders, and it doesn't work very well for creating a gradient border.
The trick to making a gradient border is to use the background to define the gradient and then use an inner box-shadow to hide the background inside the border. Here is a really ugly example.
The steps to create a border gradient are:
- Set the background to the desired gradient
- Add -moz-background-origin: border; background-origin: border-box;
- Create a border with a transparent background color
- Add a box-shadow with a large offset value that sets the actual background color. It is possible to add other inset and outset shadows as well if desired.
Example code:
p {
display: inline-block;
width: 50px;
height: 50px;
/* The background is used to specify the border background */
background: -moz-linear-gradient(45deg, #f00, #ff0);
background: -webkit-linear-gradient(45deg, #f00, #ff0);
/* Background origin is the padding box by default.
Override to make the background cover the border as well. */
-moz-background-origin: border;
background-origin: border-box;
/* A transparent border determines the width */
border: 4px solid transparent;
border-radius: 8px;
box-shadow:
inset 0 0 12px #0cc, /* Inset shadow */
0 0 12px #0cc, /* Outset shadow */
inset -999px 0 0 #fff; /* The background color */
}
The unfortunate restriction of this method is that the background is being used for the border, so you can't have both a border background gradient and a background gradient or image background inside of that. However, if you have a fixed size box (such as a button), it may be possible to use a box shadow with a large blur value to create a gradient of a specific size.