Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display x items on left, y on middle, and z on right in a row without wrapping elements?

I would like to do something similar to justify-content:space-around or justify-content:space-between, but with :

  • x items side by side on the left,
  • y items side by side on the middle,
  • z items side by side on the right.

enter image description here

It would be simple by wrap elements but I can't because these items (.left, .middle, .right) would be checkboxes influencing the styles of elements below (and there is no well-supported parent selector).

I found this answer to emulate first-of-class for the right side, but didn't find something similar to emulate last-of-class.

/* emulate first-of-class */
.container>.right {
  margin-left: auto;
}

.container>.right~.right {
  margin-left: unset;
}

Here is a snippet of my current attempt :

.container {
  display: flex;
  flex-wrap: wrap;
}

input {
  display: none;
}

label {
  padding: 0 10px;
  background-color: orange;
}

.container>.right {
  margin-left: auto;
}

.container>.right~.right {
  margin-left: unset;
}

#check-center {
  width: 100%;
  text-align: center;
}

[ lang ] {
  display: none;
}

[ name="language" ]:checked+label {
  background-color: pink;
}

[ value="en" ]:checked ~  [ lang="en" ],
[ value="en" ]:checked ~* [ lang="en" ],
[ value="fr" ]:checked ~  [ lang="fr" ],
[ value="fr" ]:checked ~* [ lang="fr" ],
[ value="es" ]:checked ~  [ lang="es" ],
[ value="es" ]:checked ~* [ lang="es" ] {
  display: block;
}

/*for codepen*/
html[ lang ] {
  display: block;
}
<div class="container">
  <input type="radio" name="left-field" id="A" />
  <label class="left" for="A">A</label>
  <input type="radio" name="left-field" id="B" />
  <label class="left" for="B">B</label>

  <input type="radio" name="middle-field" id="C" />
  <label class="middle" for="C">C</label>
  <input type="radio" name="middle-field" id="D" />
  <label class="middle" for="D">D</label>
  <input type="radio" name="middle-field" id="E" />
  <label class="middle" for="E">E</label>

  <input type="radio" name="language" id="enLang" value="en" />
  <label class="right" for="enLang">en</label>
  <input type="radio" name="language" id="frLang" value="fr" />
  <label class="right" for="frLang">fr</label>
  <input type="radio" name="language" id="esLang" value="es" />
  <label class="right" for="esLang">es</label>

  <div id="check-center">|</div>

  <div lang="en">EN selected</div>
  <div lang="fr">FR selected</div>
  <div lang="es">ES selected</div>
  <div>
    <div lang="en">EN selected</div>
    <div lang="fr">FR selected</div>
    <div lang="es">ES selected</div>
  </div>
</div>

I could cheat by adding a specific class to the last left element to apply margin-right:auto; and the first right element to apply margin-left:auto; in a display:flex container but it's not the best and even then, the middle items wouldn't be centered if the left and right parts have not the same width.

.container {
  display: flex;
  flex-wrap: wrap;
}

input {
  display: none;
}

label {
  padding: 0 10px;
  background-color: orange;
}

.cheat.left {
  margin-right: auto;
}

.cheat.right {
  margin-left: auto;
}

#check-center {
  width: 100%;
  text-align: center;
}

[ lang ] {
  display: none;
}

[ name="language" ]:checked+label {
  background-color: pink;
}

[ value="en" ]:checked ~  [ lang="en" ],
[ value="en" ]:checked ~* [ lang="en" ],
[ value="fr" ]:checked ~  [ lang="fr" ],
[ value="fr" ]:checked ~* [ lang="fr" ],
[ value="es" ]:checked ~  [ lang="es" ],
[ value="es" ]:checked ~* [ lang="es" ] {
  display: block;
}

/*for codepen*/
html[ lang ] {
  display: block;
}
<div class="container">
  <input type="radio" name="left-field" id="A" />
  <label class="left" for="A">A</label>
  <input type="radio" name="left-field" id="B" />
  <label class="cheat left" for="B">B</label>

  <input type="radio" name="middle-field" id="C" />
  <label class="middle" for="C">C</label>
  <input type="radio" name="middle-field" id="D" />
  <label class="middle" for="D">D</label>
  <input type="radio" name="middle-field" id="E" />
  <label class="middle" for="E">E</label>

  <input type="radio" name="language" id="enLang" value="en" />
  <label class="cheat right" for="enLang">en</label>
  <input type="radio" name="language" id="frLang" value="fr" />
  <label class="right" for="frLang">fr</label>
  <input type="radio" name="language" id="esLang" value="es" />
  <label class="right" for="esLang">es</label>

  <div id="check-center">|</div>

  <div lang="en">EN selected</div>
  <div lang="fr">FR selected</div>
  <div lang="es">ES selected</div>
  <div>
    <div lang="en">EN selected</div>
    <div lang="fr">FR selected</div>
    <div lang="es">ES selected</div>
  </div>
</div>

My current goal is to display elements depending on the selected language even if JavaScript is disabled, so I'm looking for a solution without JavaScript.

As HackerFrosch suggested, I tried to solve it by using a grid but I'm not used to it, the .middle items are not centered and I did not manage to make the elements below .right divs 100% width as by default.

.container {
  display: grid;
  grid-template-columns: auto 1fr auto auto auto 1fr auto auto;
}

input {
  display: none;
}

label {
  padding: 0 10px;
  background-color: orange;
  width: fit-content;
}

.cheat.left {
  margin-right: auto;
}

.cheat.right {
  margin-left: auto;
}

#check-center {
  width: 100%;
  text-align: center;
}

[ lang] {
  display: none;
}

[ name="language"]:checked+label {
  background-color: pink;
}

[ value="en"]:checked~[ lang="en"],
[ value="en"]:checked~* [ lang="en"],
[ value="fr"]:checked~[ lang="fr"],
[ value="fr"]:checked~* [ lang="fr"],
[ value="es"]:checked~[ lang="es"],
[ value="es"]:checked~* [ lang="es"] {
  display: block;
}


/*for codepen*/

html[ lang] {
  display: block;
}
<div class="container">
  <input type="radio" name="left-field" id="A" />
  <label class="left" for="A">A</label>
  <input type="radio" name="left-field" id="B" />
  <label class="cheat left" for="B">B</label>

  <input type="radio" name="middle-field" id="C" />
  <label class="middle" for="C">C</label>
  <input type="radio" name="middle-field" id="D" />
  <label class="middle" for="D">D</label>
  <input type="radio" name="middle-field" id="E" />
  <label class="middle" for="E">E</label>

  <input type="radio" name="language" id="enLang" value="en" />
  <label class="cheat right" for="enLang">en</label>
  <input type="radio" name="language" id="frLang" value="fr" />
  <label class="right" for="frLang">fr</label>
  <input type="radio" name="language" id="esLang" value="es" />
  <label class="right" for="esLang">es</label>
  <div lang="en">EN selected</div>
  <div lang="fr">FR selected</div>
  <div lang="es">ES selected</div>
  <div>
    <div lang="en">EN selected</div>
    <div lang="fr">FR selected</div>
    <div lang="es">ES selected</div>
  </div>
</div>
<div id="check-center">|</div>

Is there a way to achieve this?

like image 954
Cédric Avatar asked Jul 02 '26 11:07

Cédric


1 Answers

A solution to your problem is the css grid layout. You can customize the positioning in this example if you want. I hope that helps.

.container {
  display: grid;
  grid-template-columns: 50px auto 50px 50px auto 50px 50px 50px;
}

input {
  display: none;
}

label {
  padding: 0 10px;
  background-color: orange;
  width: 20px;
}

#check-center {
  width: 100%;
  text-align: center;
}

[ lang ] {
  display: none;
}

[ name="language" ]:checked+label {
  background-color: pink;
}

[ value="en" ]:checked ~  [ lang="en" ],
[ value="en" ]:checked ~* [ lang="en" ],
[ value="fr" ]:checked ~  [ lang="fr" ],
[ value="fr" ]:checked ~* [ lang="fr" ],
[ value="es" ]:checked ~  [ lang="es" ],
[ value="es" ]:checked ~* [ lang="es" ] {
  display: block;
}

/*for codepen*/
html[ lang ] {
  display: block;
}
<div class="container">
  <input type="radio" name="left-field" id="A" />
  <label class="left" for="A">A</label>
  <input type="radio" name="left-field" id="B" />
  <label class="left" for="B">B</label>

  <input type="radio" name="middle-field" id="C" />
  <label class="middle" for="C">C</label>
  <input type="radio" name="middle-field" id="D" />
  <label class="middle" for="D">D</label>
  <input type="radio" name="middle-field" id="E" />
  <label class="middle" for="E">E</label>

  <input type="radio" name="language" id="enLang" value="en" />
  <label class="right" for="enLang">en</label>
  <input type="radio" name="language" id="frLang" value="fr" />
  <label class="right" for="frLang">fr</label>
  <input type="radio" name="language" id="esLang" value="es" />
  <label class="right" for="esLang">es</label>

  <div id="check-center">|</div>

  <div lang="en">EN selected</div>
  <div lang="fr">FR selected</div>
  <div lang="es">ES selected</div>
  <div>
    <div lang="en">EN selected</div>
    <div lang="fr">FR selected</div>
    <div lang="es">ES selected</div>
  </div>
</div>
like image 122
HackerFrosch Avatar answered Jul 04 '26 01:07

HackerFrosch



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!