📜 ⬆️ ⬇️

Study on the replacement of standard buttons

In the process of working on the interface of a single product, there was a need to make your own button design. During this time, the code that replaces the standard button with the required one has been corresponded several times and is also far from ideal at the moment. Given all the current problems of cross-browser, during this time it turned out and it turned out below.

Suppose it should look something like this:



The button should:
  1. be inline
  2. be able to inherit parent styling (within the limits of possibilities)
  3. Inherit some properties and methods of the parent.

At the first stage, I tried to minimize the code as much as possible, creating a similar button with two containers, one of which is nested in the second with offsets to display a beautiful curved background, after all, this is not enough for the button to inherit the properties and methods that is, the button itself as an element must be present inside the containers (<span> <div> <button /> </ div> </ span>).
')
To simplify the experiment, use jQuery,

After some time, it turned out that it was extremely difficult for IE, FF, Opera to control the size and appearance of all containers with a button along with ordinary CSS. The result turned into a struggle of hacks over styles. Immediately I first encountered the need to write different styles for FF2 and FF3.

In the end, the concept used in ExtJS, namely the table, was taken as the basis.

[left edge | button | right edge]

In this regard, the number of positioning issues has decreased significantly, and with it the number of CSS.

Cheat codes



Assume that the source buttons are set as follows.
<input type = 'submit' value = 'Submit' class = 'replaceMe w100'>
<input type = 'button' value = 'Pushme' class = 'replaceMe ico ico-image' disabled = 'disabled'>


In this case, it turns out that the replaceMe class will be the selector for the replacement, the w100 class is an auxiliary class (for example, responsible for the width of the button) to be inherited. ico and ico-image - classes responsible for the icons.

Picture sprite for the prototype:
image

CSS prototype:
.ico {
padding-left: 20px !important;
padding-bottom: 1px !important;
background-position: 0px 0px;
background-repeat: no-repeat;
}

.ico-image { background-image: url( "page_tick.gif" ) !important;}

/* */
.xBtn tr td {
border: 0 none !important;
border-bottom: 0 none !important;
padding: 0;
font:normal 11px sans-serif, tahoma, verdana, helvetica ;
height: 21px;
min-height: 21px;
}

/* */
.xBtn {
cursor:pointer;
border-collapse: collapse;
white-space: nowrap;
display: inline;
width: auto;
}

/* . , .
* , IE : ,
* padding: 0 1.3em;
* */
.xBtn button {
border:0 none;
background:transparent no-repeat;
font:normal 11px tahoma,verdana,helvetica;
padding-left:3px;
padding-right:3px;
height: 21px;
cursor:pointer;
margin:0;
overflow:visible;
width:auto;
-moz-outline:0 none;
outline:0 none;
}

/* IE */
* html .xBtn button {width: 1px;}
*+html .xBtn button {width: 1px;}
*+html .xBtn button {padding-top:3px;}

/* */
.xBtn .xBtn-text-ico {
background-position: 0 0px;
background-repeat: no-repeat;
height: 16px;
padding: 0 0 2px 18px;
margin-top: 1px;
}

/* */
.xBtn .xBtn-text {
background-position: 0 0px;
background-repeat: no-repeat;
padding-top:0px;
padding-bottom:2px;
padding-right:0;
margin-top: 1px;
height: 16px;
}

/* IE */
*+html .xBtn .xBtn-text { padding-top:1px; margin-top: 2px;}

.xBtn-Left, .xBtn-Right {
font-size:1px;
line-height:1px;
width:3px;
height:21px;
}

.xBtn-Left { background: url(btn-sprite.png) no-repeat 0 0;}
.xBtn-Right { background: url(btn-sprite.png) no-repeat 0 -21px;}

.xBtn .xBtn-Left i, .xBtn .xBtn-Right i {
display:block;
width:3px;
overflow:hidden;
font-size:1px;
line-height:1px;
}

.xBtn .xBtn-Center {
background:url(btn-sprite.png) repeat-x 0 -42px;
vertical-align: middle;
text-align:center;
cursor:pointer;
white-space:nowrap;
}

.xBtn-over .xBtn-Left{ background: url(btn-sprite.png) repeat-x 0 -63px !important; }
.xBtn-over .xBtn-Right{ background: url(btn-sprite.png) repeat-x 0 -84px !important; }
.xBtn-over .xBtn-Center { background: url(btn-sprite.png) repeat-x 0 -105px !important;}
.xBtn-click .xBtn-Left { background: url(btn-sprite.png) repeat-x 0 -126px !important;}
.xBtn-click .xBtn-Right { background: url(btn-sprite.png) repeat-x 0 -147px !important; }
.xBtn-click .xBtn-Center { background: url(btn-sprite.png) repeat-x 0 -168px !important; }

.xBtn em {
font-style:normal;
font-weight:normal;
height: 16px;
}


* This source code was highlighted with Source Code Highlighter .


And actually, the code itself:
$( '.replaceMe' ).each( function (){
//
$( this ).removeClass( 'replaceMe' );

//
var BtnTable = document .createElement( 'table' );
var BtnTableRow = BtnTable.insertRow(0);
var LeftBtnCell = BtnTableRow.insertCell(0);
var CenterBtnCell = BtnTableRow.insertCell(1);
var RightBtnCell = BtnTableRow.insertCell(2);

// ,
// - DOM
var newBtnContainer = document .createElement( 'em' );
var newBtnSideLContainer = document .createElement( 'i' );
var newBtnSideRContainer = document .createElement( 'i' );

// ,
$(LeftBtnCell).addClass( 'xBtn-Left' ).append(newBtnSideLContainer);
$(RightBtnCell).addClass( 'xBtn-Right' ).append(newBtnSideRContainer);

// ,
//
newBtnContainer.setAttribute( 'uselectable' , 'on' );

$(BtnTable)

// -
.addClass( 'xBtn' )

// Title,
.attr( 'title' , $( this ).attr( 'value' ) || '' )

// -
.hover(
function (){
if ($( 'button:enabled' , $(BtnTable)).length) $( this ).addClass( 'xBtn-over' );
},
function (){
$( this ).removeClass( 'xBtn-over' );
$( this ).removeClass( 'xBtn-click' );
}
)
.mousedown( function (){
//$(newBtn).focus();
$( this ).addClass( 'xBtn-click' );
})
.mouseup( function (){
$( this ).removeClass( 'xBtn-click' );
});

// ,
// , - .
// ico ico-image

// , , ...
var xBtnClasses = this .className.split( ' ' );
var hasIco = $( this ).hasClass( 'ico' );
var icoClassName = '' ;
for ( var i = 0; i < xBtnClasses.length; i++ ) {
if (xBtnClasses[i].toString().match(/ico-\w+/)) icoClassName = xBtnClasses[i].toString();
}

// .
if (hasIco && icoClassName) {
$( this ).removeClass( 'ico' ).removeClass(icoClassName)
}

// ( )
//
$(CenterBtnCell).append(newBtnContainer).addClass( this .className).addClass( 'xBtn-Center' );;

// onclick
var onClickEv = $( this ).attr( 'onclick' );

// , -
if (jQuery.isFunction(onClickEv)) {
$(BtnTable).bind( 'click' , function (e){
onClickEv();
});

// , submit-?
//
} else if ( this .type == 'submit' ) {
$(BtnTable).bind( 'click' , function (e){
if ($( this ).find( 'button' ).length) {
var f = $( this ).find( 'button' )[0];
f.click();
}
});
}

//
$( this ).hide().before(BtnTable);

// JavaScript.
// IE, type
// :

var Btn = '<button ' +
//
'type="' + ($( this ).attr( 'type' ) || 'button' ) + '" ' +

// ID
'id="' + this .id + '" ' +

// : , ,
'class="' + ((hasIco && icoClassName) ? 'xBtn-text-ico ico ' + icoClassName : 'xBtn-text' ) + (($( this ).attr( 'disabled' )) ? ' disabled"' : '' ) + '" ' +

//
(($( this ).attr( 'disabled' )) ? 'disabled="disabled"' : '' ) +
'name="' + $( this ).attr( 'name' ) + '" ' +
'title="' + $( this ).attr( 'title' ) + '" ' +
'style="' + (($( this ).attr( 'value' ) == '' ) ? 'width:16px;' : '' ) + '" ' +
'>' + $( this ).attr( 'value' ) +
'</button>' ;

// Tadaaaa!
newBtnContainer.innerHTML = Btn;

// IE, , ,
if ($.browser.msie && $( this ).attr( 'value' ) != '' ) {
if ($(CenterBtnCell).width()) {
$(CenterBtnCell).find( 'button' ).css( 'width' , $(CenterBtnCell).width() + 'px' );
} else {
$(CenterBtnCell).find( 'button' ).css( 'width' , TextMetrixWidth( this ) + 18 + 'px' );
}
}

$( this ).remove();
});

* This source code was highlighted with Source Code Highlighter .


Thank you very much for your attention. I hope that the knowledge gained by me in the process of work was useful.

update: Demonstration of work, at the request of workers.

Source: https://habr.com/ru/post/56846/


All Articles