The appearance of this technique contributed to a truly monstrous layout of page elements on our project. Just think, to display one button it took up to seven tags per item.
It looked like this:

')
html< div class ="large_button" > <br> < span class ="buttons submit_v2-button clickable" > <br> < i class ="left left2" ></ i > <br> < i class ="body" > <br> < b > </ b > <br> < i class ="end" > <br> < i ></ i > <br> </ i > <br> </ i > <br> </ span > <br> </ div >
It can be seen that getting into this code is easier than ever, especially since the options for buttons on the project have accumulated at least 30. Attempting to create such a button on the server side caused resentment among the pehapist colleagues.
Therefore, my unspoken task was to maximize the simplification of the code.
Initially, the idea appeared to make all the buttons without using images at all, as was described in
one of the articles of Habr.
Unfortunately, in this case, to achieve cross-browser compatibility is somewhat more difficult, and I, as a user, do not like CSS shny shadows (as a layout designer, I adore them).
The solution, which completely suited me, was found in the use of pseudo-elements: before and: after.
The first step was the systematization. All buttons were sorted into groups by size, image and main background.
To make it all good, all button graphics was merged into one
sprite .
As a result, it gave decent savings in the total amount of images and the number of http requests.
I must say that I was very lucky with the team, with which we eventually eventually abandoned the
necrophilia of supporting our site in Internet Explorer 6.
Two weeks later from the aforementioned significant event, a completely wonderful, in my opinion, version of the button layout appeared:
html< div class ="neobtn-thick" > </ div >
css/* */
*[class*=neobtn]{
text-shadow: 0 1px 0 #ddd;
cursor: pointer;
background-color: transparent;
display: inline-block;
background-image: url(../images/buttons/buttons.png);
white-space: nowrap;
}
*[class*=neobtn]:before{
background-image: url(../images/buttons/buttons.png);
content: '';
float: left;
}
*[class*=neobtn]:after{
background-image: url(../images/buttons/buttons.png);
content: '';
float: right;
}
/* . 46px */
*[class*=neobtn-thick]{
height: 46px;
margin: 0 25px 0 45px;
line-height: 45px;
font-size: 24px;
background-position: 0 -153px;
}
*[class*=neobtn-thick]:before{
height: 46px;
width: 45px;
background-position: 0 -245px;
margin: 0 0 0 -45px;
}
*[class*=neobtn-thick]:after{
height: 46px;
width: 25px;
margin: 0 -25px 0 0;
background-position: 0 -199px;
}
/* */
*[class*=neobtn-thick-create]:before{background-position: 0 -291px;}
*[class*=neobtn-thick-go]:before{background-position: 0 -429px;}
*[class*=neobtn-thick-down]:before{background-position: 0 -567px;}
The essence of the method is extremely simple, which can be overlooked during a cursory examination. To any element that has the word “neobtn” in the class name, we add the basic “button” properties. Then the properties of the element are specified by adding modifiers (in our example, this is “-thick”).
You can modify the element as you like, not forgetting to remain within the bounds of the reasonable.
For Internet Explorer 7, the code is almost the same, only instead of pseudo-elements, the insertAdjacentHTML method is used to create the HTML elements we need, and instead of indents, absolute positioning is used.
css*[class*=neobtn]{
zoom: expression(runtimeStyle.zoom = 1,
insertAdjacentHTML('afterBegin',' < div class ="before" ></ div >< div class ="after" ></ div > '));
position: relative;
display: inline;
}
.before,
.after{
background-image: url(../images/buttons/buttons.png);
top: 0;
position: absolute;
}
/* BUTTONS */
/* 46px */
*[class*=neobtn-thick] .before{
height: 46px;
width: 45px;
background-position: 0 -245px;
left: -45px;
}
*[class*=neobtn-thick] .after{
height: 46px;
width: 25px;
right: -25px;
background-position: 0 -199px;
}
*[class*=neobtn-thick-create] .before{
background-position: 0 -291px;
}
*[class*=neobtn-thick-go] .before{
background-position: 0 -429px;
}
*[class*=neobtn-thick-down] .before{
background-position: 0 -567px;
}
It makes sense to put this CSS code in a separate file, connect it only for Internet Explorer 7 users through conditional comments, so that you can get rid of it without any serious consequences:
<!--[if IE 7]><link rel="stylesheet" type="text/css" media="screen" href="/css/buttons_ie.css" /><![endif]-->
Minor refinements of the method allow you to decorate a submit type button:
html< div class ="neobtn-thick" >< input type ="submit" value ="" /></ div >
css*[class*=neobtn-thick] input[type=submit]{<br> margin: 0 -17px 0 -37px;<br> padding: 0 12px 0 33px;<br> height: 46px;<br> font-size: 100%;<br> font-family: Arial;<br> text-shadow: 0 1px 0 #ddd;<br> color: #222;<br>}
And if you want to insert an arbitrary image into the button, you need to add one more element and make the desired image as its background:
html< div class ="neobtn-thick" >< span class ="delete" ></ span > </ div > <br><br>
css.delete {<br> background url(url);<br> width: 00px;<br> height: 00px;<br> display: inline-block;<br>}<br>
The beauty of this method is to use the asterisk selector, which allows you to make a button from any tag, without fear that instead of “neobtn-thick-create” you write “trololoNEOBTN-THICK-CREATElo”.
The only important problem in this case is to come up with the first word in the class name so that it is not part of the class name of the other elements. For example, you should not use obvious words like "button" or "btn". It is for this reason that in the examples class names begin with “neobtn”.
Adding new buttons is also not a big deal:
- We draw new images in general sprite
- We add the corresponding rules to css
- PROFIT!
The method has negative sides:
- The use of the asterisk selector slows down the page rendering process somewhat. However, it is worth noting that no matter how significant a delay I have not been able to achieve. The number of buttons on the page does not exceed one or two dozen, and taking into account the reduction in the number of tags, the difference in speed is leveled.
- When scaling in the “text only” mode, everything will fall apart.
Theoretically, it would be possible to write the names of classes and modifiers separately:
< div class ="button button-thick button-thick-create" > </ div > <br>
but in this case some kind of redundancy and tautology would arise.
As a result, I got something between advanced and “classic” technologies of html-layout.
This method can also create drop-down lists, decorate water fields and, probably, a lot more.
ExampleThe same
article on my site.
Update # 1: More about the
universal selectorUpdate # 2: If you are worried about the asterisk selectors before the attribute selectors, you can easily get rid of them. The layout of the buttons will not be affected.