Search code examples
csscheckboxvertical-alignment

Vertically aligning a checkbox


I have looked at the different questions regarding this issue, but couldn't find anything that works due to limitations in my markup.

My markup looks like so (unfortunately as this is generated by some backend, I am unable to change the markup).

<ul>        
    <li>
        <input type="checkbox" value="1" name="test[]" id="myid1">
        <label for="myid1">label1</label>
    </li>
    <li>
        <input type="checkbox" value="2" name="test[]" id="myid2">
        <label for="myid2">label1</label>
    </li>
</ul>

I need the checkbox to be on the right and centered vertically in the <li>

Currently, this is styled as:

li input{
   display: inline-block;
   float: right;
   margin-right: 10px;
}

I have tried using various values for vertical-align, but that doesn't seem to help. Also, in some cases the label can be very long and span multiple lines. The checkbox would still need to be able to vertically center itself when the height of the li is arbitrary.

How can I go about achieving this?


Solution

  • Vertical alignment only works on inline elements. If you float it, then I don't think it is treated as part of that stream of inline elements any more.

    Make the label an inline-block, and use vertical alignment on both the label and the input to align their middles. Then, assuming it is okay to have a specific width on the labels and checkboxes, use relative positioning instead of floating to swap them (jsFiddle demo):

    input {
        width: 20px;
    
        position: relative;
        left: 200px;
             
        vertical-align: middle;
    }
    
    label {  
        width: 200px;
        
        position: relative;
        left: -20px;
        
        display: inline-block;
        vertical-align: middle;
    }
    

    2024 update, using Flexbox (fiddle):

    ul {
      width: 300px; /* Only for demonstration. */
      border: 1px dashed gray;
    }
    
    li {
        display: flex;
        flex-direction: row-reverse; /* Only needed for swapping their order. */
        align-items: center;
    }
    
    input {
        background-color: blue;
    }
    
    label {
        background-color: red;
        flex-grow: 1; /* Grow the label to fill available space, pushing the checkboxes to the edge of the container. */
    }
    

    Less hacky, and with this you don't need to specify any widths. It will grow to fill the container, and wrap if necessary.

    Another alternative would be Flexbox Grid.