Richard
Richard

Reputation: 65510

Align checkbox and label horizontally?

I am trying to create a legend inside a fixed-width div, containing coloured checkboxes and a label for each checkbox. My problem is that longer labels break over two lines and push the label down below the checkbox, which looks bad:

enter image description here

How can I get the checkbox and the label on the same line, but retaining the line break, and ensuring that "France" and "territories" both have the same left indent, rather than "territories" having the same indent as the checkbox?

JSFiddle: https://jsfiddle.net/6yLd6j1b/10/

Full code:

<div id='legend'>
<div class="legend-container" id="areas">

  <div class="checkbox france">
    <input type="checkbox" checked="checked" class="area_type" id="france">  
    <label for="france"></label><div class="tag">France and its overseas territories</div>
  </div>

  <div class="checkbox germany">
    <input type="checkbox" checked="checked" class="area_type" id="germany">
     <label for="germany"></label><div class="tag">Germany</div>
  </div>

</div>
</div>

#legend {
    width: 200px;
}
#legend div {
    margin-right: 5px;
}
.checkbox {
  margin: 0 0 1.2em 0;
  clear: both;
  cursor: pointer;
}
.checkbox .tag {
  display: block;
  float: left;
}
.checkbox .area_type {
  display: none;
}
.area_type + label {
  cursor: pointer;
  -webkit-appearance: none;
  background-color: #fafafa;
  border: 1px solid #cacece;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), inset 0px -15px 10px -12px rgba(0, 0, 0, 0.05);
  padding: 7px;
  display: block;
  float: left;
  position: relative;
  top: 2px;
  overflow: hidden;
  border-radius: 5px;
  margin-right: 5px;
}
.area_type:checked + label:after {
  width: 100%;
  height: 100%;
  content: "";
  position: absolute;
  left: 0px;
  top: 0px;
}
.france .area_type:checked + label:after {
  background-color: #2c98a0; 
}
.germany .area_type:checked + label:after {
  background-color: #38b2a3;
}

Upvotes: 0

Views: 1561

Answers (2)

VXp
VXp

Reputation: 12058

You can do it with the Flexbox if you add display: inline-flex and align-items: flex-start to the .checkbox class:

#legend {
  background-color: #ccc;
  border-radius: 3px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.10);
  padding: 10px;
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1;
  width: 200px;
}

#legend div {
  margin-right: 5px;
}

.checkbox {
  margin: 0 0 1.2em 0;
  clear: both;
  cursor: pointer;
  display: inline-flex; /* only takes the content's width, but in your case "display: flex" also works just fine */
  align-items: flex-start; /* prevents the default vertical stretching of flex-items */
}

.checkbox .tag {
  display: block;
  float: left;
}

.checkbox .area_type {
  display: none;
}
.area_type + label {
  cursor: pointer;
  -webkit-appearance: none;
  background-color: #fafafa;
  border: 1px solid #cacece;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), inset 0px -15px 10px -12px rgba(0, 0, 0, 0.05);
  padding: 7px;
  display: block;
  float: left;
  position: relative;
  top: 2px;
  overflow: hidden;
  border-radius: 5px;
  margin-right: 5px;
}

.area_type:checked + label:after {
  width: 100%;
  height: 100%;
  content: "";
  position: absolute;
  left: 0px;
  top: 0px;
}

.france .area_type:checked + label:after {
  background-color: #2c98a0; 
}

.germany .area_type:checked + label:after {
  background-color: #38b2a3;
}
<div id='legend'>
  <div class="legend-container" id="areas">
    <div class="checkbox france">
      <input type="checkbox" checked="checked" class="area_type" id="france">  
      <label for="france"></label><div class="tag">France and its overseas territories</div>
    </div>
    <div class="checkbox germany">
      <input type="checkbox" checked="checked" class="area_type" id="germany">
      <label for="germany"></label><div class="tag">Germany</div>
    </div>
  </div>
</div>

Upvotes: 2

scooterlord
scooterlord

Reputation: 15339

I took the liberty of correctly wrapping the input[type="checkbox"] inside the label so that it toggles the checkbox for better user experience. Obviously this required some markup changes as well.

Bonus tip: I didn't want to mess any more than necessary with your initial code, but try using more semantic code and simpler logic - for example the .checkbox class should be applied on the checkbox itself and not around it. Also with the new markup the <div class="checkbox france"> could become obsolete, since you might as well have used the label.country class to target specific elements.

HTML:

<div id='legend'>
  <div class="legend-container" id="areas">

    <div class="checkbox france">
      <label for="france">
        <input type="checkbox" checked="checked" class="area_type" id="france">  
        <span class="tag">France and its overseas territories</span>
      </label>
    </div>

    <div class="checkbox germany">
      <label for="germany">
        <input type="checkbox" checked="checked" class="area_type" id="germany">
        <span class="tag">Germany</span>
      </label>
    </div>

  </div>
</div>

CSS:

#legend {
  width: 200px;
}

#legend div {
  margin-right: 5px;
}

.checkbox {
  margin: 0 0 1.2em 0;
  clear: both;
  cursor: pointer;
}

.checkbox {
  position: relative;
}

.area_type {
  position: absolute;
  visibility: hidden;
  opacity: 0;
}

.area_type+span {
  display: block;
  margin-left: 25px;
}

.area_type+span:before {
  content: "";
  cursor: pointer;
  -webkit-appearance: none;
  background-color: #fafafa;
  border: 1px solid #cacece;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), inset 0px -15px 10px -12px rgba(0, 0, 0, 0.05);
  padding: 7px;
  display: block;
  overflow: hidden;
  border-radius: 5px;
  margin-right: 5px;
  position: absolute;
  left: 0;
  top: 2px;
}

.france .area_type:checked+span:before {
  background-color: #2c98a0;
}

.germany .area_type:checked+span:before {
  background-color: #38b2a3;
}

Here is a working fiddle: https://jsfiddle.net/y74qanps/

Upvotes: 1

Related Questions