📜 ⬆️ ⬇️

Split button dropdown without javascript

Good day to all!

Most recently, I needed to create a kind of multi-action control for the list of entries. The use of the split button dropdown immediately came to mind, i.e. in this case, the form submission button combined with the drop-down list of actions. Such controls are not rarely found in modern interfaces. There are also ready-made solutions included in assemblies like Twitter Bootstrap .

However, implementations like Bootstrap do not like for several reasons:

It is for these reasons that I decided to patch up my own version of this control. At once I want to note that all the ideas were never implemented, therefore the method does not pretend to completely replace js solutions. Again, I post it only for those who will be useful.
')
Actually, the decision is based on the idea presented by me in the article Simple customization of Checkbox and Radio .

I want to note right away that the example below is simplified, so it may not be completely cross-browser. In it, I decided not to focus on the full layout of styles, the use of browser prefixes for properties, polylifil, etc. Although the option is no doubt quite working.
Further only the code.

Markup

< button id = "action" > Action < / button >
< label for = "action" > & # x25bc;
< ul >
< li title = "Edit selected" > < input id = "edit" type = "radio" name = "action" value = "edit" hidden checked / > < label for = "edit" > Edit < / label > < / li >
< li title = "Delete selected" > < input id = "delete" type = "radio" name = "action" value = "delete" hidden / > < label for = "delete" > Delete < / label > < / li >
< li title = "Mark selected as read" > < input id = "read" type = "radio" name = "action" value = "read" hidden / > < label for = "read" > Read < / label > < / li >
< li title = "Mark selected as spam" > < input id = "spam" type = "radio" name = "action" value = "spam" hidden / > < label for = "spam" > Spam < / label > < / li >
< / ul >
< / label >

Styles

button , label { cursor : pointer ; }
button ,
button + label {
float : left ;
display : inline- block ;
margin : 0 ;
background : # 659A22 repeat-x ;
background-image : -webkit-linear-gradient ( top , # 9AC92C , # 659A22 ) ;
background-image : -o-linear-gradient ( top , # 9AC92C , # 659A22 ) ;
background-image : -moz-linear-gradient ( top , # 9AC92C , # 659A22 ) ;
background-image : linear-gradient ( top , # 9AC92C , # 659A22 ) ;
border : 1px solid rgba ( 0 , 0 , 0 , 0.0976563 ) ;
border-bottom-color : rgba ( 0 , 0 , 0 , 0.246094 ) ;
border-top-color : rgba ( 255 , 255 , 255 , 0.148438 ) ;
color : #fff ;
font-size : 13px ;
cursor : pointer ;
font-family : 'Helvetica Neue' , Helvetica , Arial , sans-serif ;
line-height : 16px ;
padding : 5px 10px ;
text-shadow : # 659A22 1px 1px 0px ;
-webkit-transition : 0.1s linear all ;
transition : 0.1s linear all ;
vartical-align : middle ;
}
button : hover , button + label : hover {
text-decoration : none ;
background-color : # 659A22 ;
background-position : 0 -15px ;
-webkit-transition : background-position 0.1s linear ;
-o-transition : background-position 0.1s linear ;
-moz-transition : background-position 0.1s linear ;
transition : background-position 0.1s linear ;
}
button { border-top-left-radius : 3px ; border-bottom-left-radius : 3px ; }
button : active {
color : #fff ;
box-shadow : inset 0 2px 4px rgba ( 0 , 0 , 0 , 0.15 ) , 0 1px 2px rgba ( 0 , 0 , 0 , 0.05 ) ;
}
button + label {
border-top-right-radius : 3px ;
border-bottom-right-radius : 3px ;
position : relative ;
}
button + label : hover > ul {
visibility : visible ;
opacity : 1 ;
margin : 0 ;
}
ul {
visibility : hidden ;
position : absolute ;
top : 30px ;
right : 0 ;
width : 90px ;
margin : 20px 0 0 0 ;
padding : 10px 0 ;
z-index : 9999 ;
border : 1px solid #ccc ;
border-top-clor : #cfcfcf ;
border-image : initial ;
background : #fff ;
color : # 659A22 ;
text-shadow : none ;
opacity : 0 ;
box-shadow : 1px 2px 4px rgba ( 0 , 0 , 0 , 0.2 ) ;
border-radius : 3px ;
transition : all 0.2s ease-in-out ;
-webkit-transition : all 0.2s ease-in-out ;
-moz-transition : all 0.2s ease-in-out ;
-o-transition : all 0.2s ease-in-out ;
}

ul li {
float : none ;
display : block ;
border : 0 ;
line-height : 20px ;
}
ul li input [ type = "radio" ] { display : none ; }
ul li input [ type = "radio" ] + label {
font-size : 14px ;
width : 70px ;
display : list-item ;
list-style : none ;
vertical-align : baseline ;
padding : 2px 10px ;
}
ul li input [ type = "radio" ] + label : hover , ul li input [ type = "radio" ] : checked + label {
background-color : # 659A22 ;
background-repeat : repeat-x ;
background-image : -webkit-linear-gradient ( top , # 9AC92C , # 659A22 ) ;
background-image : -moz-linear-gradient ( top , # 9AC92C , # 659A22 ) ;
background-image : -o-linear-gradient ( top , # 9AC92C , # 659A22 ) ;
background-image : linear-gradient ( top , # 9AC92C , # 659A22 ) ;
color : #fff ;
text-shadow : none ;
}
ul li input [ type = "radio" ] + label : hover {
box-shadow : inset 0 2px 4px rgba ( 0 , 0 , 0 , 0.15 ) , 0 1px 2px rgba ( 0 , 0 , 0 , 0.05 ) ;
}


Here is a demo in which I also added a form and js to catch its sending, which displays an alert with an action value: Demo . Accordingly, in exactly the same way, you can send several actions using checkboxes instead of radio buttons.

At the end

So what happened and what did not:

Happened:


Did not work out:



About the last point I will clarify. I was hoping to implement sending the form by clicking on the radio buttons without having to catch events using javascript. More specifically, the click should have taken place on the button itself, by using the same method with the label , as well as the “ascent” effect. However, this method took effect only in Opera . She manages to successfully process and click on the label attached to the radio button and click on the label attached to the button and actually sends the form. All other browsers do an interesting thing - the button seems to be pressed, which can be noticed due to the effect on the button: active , but the form is not sent.

In fact, I do not know the reason yet. Either this is again the differences in the interpretation of the specification by the browsers, or I have been fixing it somewhere. If someone has any ideas, please share in the comments.

UPD: A version of the implementation of similar controls from ibnteo , you can see here . For those who desperately need to send the form by clicking on the list item without js, as well as expanding the list by clicking, but the markup doesn’t care much, this option may be fine. Thank you, ibnteo.

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


All Articles