How do I align switches and labels?

I am developing a 3rd party system integration and I need to format some radio buttons. The vendor gives us this HTML:

<span class="radiocontainer">
    <label for="genderMale" class="radiolabel">Male</label>
    <input class="selector" id="genderMale" name="Gender" type="radio" value="2">
    <label for="genderFemale" class="radiolabel">Female</label>
    <input class="selector" id="genderFemale" name="Gender" type="radio" value="1">
</span>

      

and I need it to look like this:

Correct layout

I have tried and failed to do the following using flexbox:

span.radiocontainer {
  float: none;
  display: flex;
  align-items: left;
  justify-content: left;
  flex-direction: column;
  flex-wrap: wrap;
  align-content: left;
}

span.radiocontainer > label.selected.radiolabel {
  box-shadow: none;
  width: 50%;
  border: 0px;
}

span.radiocontainer > input {
  width: 50%;
}
      

<span class="radiocontainer">
    <label for="genderMale" class="radiolabel">Male</label>
    <input class="selector" id="genderMale" name="Gender" type="radio" value="2">
    <label for="genderFemale" class="radiolabel">Female</label>
    <input class="selector" id="genderFemale" name="Gender" type="radio" value="1">
</span>
      

Run codeHide result


Current layout

Is there a way to format the radio buttons on the left? Or do I need to change my design?

I can't change the HTML like the vendor, CSS is the only thing we can customize.

+3


source to share


3 answers


CSS grid

The most suitable approach here is CSS Grid Layout . The approach below uses modern syntax but does not support IE / Edge.

.radiocontainer {
  display: inline-grid;
  /* tells the auto-placement algorithm to attempt to fill in holes earlier in the grid if smaller items come up later */
  grid-auto-flow: dense;
  align-items: center;
}

.radiocontainer label {
  grid-column: 2;
}
      

<span class="radiocontainer">
    <label for="genderMale" class="radiolabel">Male</label>
    <input class="selector" id="genderMale" name="Gender" type="radio" value="2">
    <label for="genderFemale" class="radiolabel">Female</label>
    <input class="selector" id="genderFemale" name="Gender" type="radio" value="1">
</span>
      

Run codeHide result


If you also need IE and Edge support, you will have to use the old syntax. There is no auto-placement behavior in the IE / Edge implementation, so you have to manually determine the alignment of each element (except the first). If you don't position the elements, they will stack in the first cell of the grid in IE / Edge. This works in IE10 +:

.radiocontainer {
  display: -ms-inline-grid;
  display: inline-grid;
  align-items: center;
}

.radiocontainer label {
  display: block;
}

input:nth-of-type(2) {
  -ms-grid-row: 2;
  grid-row: 2;
}

label:nth-of-type(1) {
  -ms-grid-row: 1;
  grid-row: 1;
  -ms-grid-column: 2;
  grid-column: 2;
}

label:nth-of-type(2) {
  -ms-grid-row: 2;
  grid-row: 2;
  -ms-grid-column: 2;
  grid-column: 2;
}

input:nth-of-type(3) {
  -ms-grid-row: 3;
  grid-row: 3;
}
      

<span class="radiocontainer">
    <label for="genderMale" class="radiolabel">Male</label>
    <input class="selector" id="genderMale" name="Gender" type="radio" value="2">
    <label for="genderFemale" class="radiolabel">Female</label>
    <input class="selector" id="genderFemale" name="Gender" type="radio" value="1">
    <input class="selector" id="asdf" name="Gender" type="radio" value="1">
</span>
      

Run codeHide result


Flexbox

I would improve @ NenadVracar's answer :



  • We can remove the need to install order

    for each item. We can just install flex-direction: row-reverse

    for the container.

  • The percent ( 50%

    ) value for input

    and label

    is a bad idea. Increasing / decreasing the length of the labels will distort our list of radio buttons. We need to set a fixed width for the switch.

.radiocontainer {
  display: inline-flex;
  flex-direction: row-reverse;
  flex-wrap: wrap;
  align-items: center;
}

.radiocontainer input,
.radiocontainer label {
  margin: 0;
}

.radiocontainer input {
  width: 20px;
}

.radiocontainer label {
  width: calc(100% - 20px);
}
      

<span class="radiocontainer">
    <label for="genderMale" class="radiolabel">Male</label>
    <input class="selector" id="genderMale" name="Gender" type="radio" value="2">
    <label for="genderFemale" class="radiolabel">Female</label>
    <input class="selector" id="genderFemale" name="Gender" type="radio" value="1">
</span>
      

Run codeHide result


CSS floats

This way will work even in IE9, but centering the radio buttons doesn't work.

If you see @TejasviKarne you will notice that the width .radiocontainer

does not take into account the width label

. If you are worried about it, you can do it like this:

.radiocontainer {
  display: inline-block; /* Take width of content */
}

.radiocontainer input,
.radiocontainer label {
  margin: 0;
}

.radiocontainer label {
  width: calc(100% - 15px);
  float: right;
}
      

<span class="radiocontainer">
    <label for="genderMale" class="radiolabel">Male</label>
    <input class="selector" id="genderMale" name="Gender" type="radio" value="2">
    <label for="genderFemale" class="radiolabel">Female</label>
    <input class="selector" id="genderFemale" name="Gender" type="radio" value="1">
</span>
      

Run codeHide result


+3


source


You can hardcode the inputs to the left for each input and label.



.radiocontainer {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
}
.radiocontainer input,
.radiocontainer label {
  width: 50%;
  margin: 0;
}

input:nth-of-type(1) {order: 1}
input:nth-of-type(2) {order: 3}
label:nth-of-type(1) {order: 2}
label:nth-of-type(2) {order: 4}
      

<span class="radiocontainer">
    <label for="genderMale" class="radiolabel">Male</label>
    <input class="selector" id="genderMale" name="Gender" type="radio" value="2">
    <label for="genderFemale" class="radiolabel">Female</label>
    <input class="selector" id="genderFemale" name="Gender" type="radio" value="1">
</span>
      

Run codeHide result


+3


source


I am shooting in the dark here but will comment all your code and try

label{float:right; width:calc(100% - 30px);}

      

.radiocontainer label{float:right; width:calc(100% - 30px);}
      

<span class="radiocontainer">
    <label for="genderMale" class="radiolabel">Male</label>
    <input class="selector" id="genderMale" name="Gender" type="radio" value="2">
    <label for="genderFemale" class="radiolabel">Female</label>
    <input class="selector" id="genderFemale" name="Gender" type="radio" value="1">
</span>
      

Run codeHide result


I removed all the original styles in the script you provided and added only those styles. They lined up the way you wanted. However, your stylesheet may contain other styles such as line-height

and margin

. I think you can get the alignment you want with some tweaking. If it doesn't work, you can go back to your code and continue from there. Let me know how it goes.

+1


source







All Articles