Solution 1 :

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>

Solution 2 :

You can try to solve this with flex and use the calc() function to manage the left or right margins. So, I created four classes to use one of them to center the middle classes.

/* adjust for left side, put to the first middle label */
.one-left.middle {
  margin-inline-start: calc((4 * var(--block-width) / 2));
}
.two-left.middle {
  margin-inline-start: calc((3 * var(--block-width) / 3));
}

/* adjust for right side, set to the last meddle label */
.one-right.middle {
  margin-inline-end: calc((4 * var(--block-width) / 2));
}
.two-right.middle {
  margin-inline-end: calc((3 * var(--block-width) / 3));
}

Usage .two-left.middle

*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  --block-width: 50px;
  display: flex;
  justify-content: center;
}

.gap.left {
  margin-inline-end: auto;
}

.gap.right {
  margin-inline-start: auto;
}


/* adjust for left side, put to the first middle label */
.one-left.middle {
  margin-inline-start: calc((4 * var(--block-width) / 2));
}

.two-left.middle {
  margin-inline-start: calc((3 * var(--block-width) / 3));
}


/* adjust for right side, set to the last meddle label */
.one-right.middle {
  margin-inline-end: calc((4 * var(--block-width) / 2));
}

.two-right.middle {
  margin-inline-end: calc((3 * var(--block-width) / 3));
}

input {
  display: none;
}

label {
  padding: 0 10px;
  background-color: orange;
  width: var(--block-width);
}

#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;
}
<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="A1" />
      <label class="left" for="A1">A1</label> -->
  <input type="radio" name="left-field" id="B" />
  <label class="gap left" for="B">B</label>

  <input type="radio" name="middle-field" id="C" />
  <label class="two-left 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="gap 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>

Usage .one-right.middle

*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  --block-width: 50px;
  display: flex;
  justify-content: center;
}

.gap.left {
  margin-inline-end: auto;
}

.gap.right {
  margin-inline-start: auto;
}


/* adjust for left side, put to the first middle label */
.one-left.middle {
  margin-inline-start: calc((4 * var(--block-width) / 2));
}

.two-left.middle {
  margin-inline-start: calc((3 * var(--block-width) / 3));
}


/* adjust for right side, set to the last meddle label */
.one-right.middle {
  margin-inline-end: calc((4 * var(--block-width) / 2));
}

.two-right.middle {
  margin-inline-end: calc((3 * var(--block-width) / 3));
}

input {
  display: none;
}

label {
  padding: 0 10px;
  background-color: orange;
  width: var(--block-width);
}

#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;
}
<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="A1" />
  <label class="left" for="A1">A1</label> 
  <input type="radio" name="left-field" id="B" />
  <label class="gap 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="one-right middle" for="E">E</label>

  <input type="radio" name="language" id="enLang" value="en" />
  <label class="gap 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>

Solution 3 :

Something like this – using left margin auto on the first center and right classes:

/* flex container */
.container { display: flex; }

/* left margin auto on all center/right classes */
.center, .right { margin-left: auto; }

/* remove auto margin on non firsts */
.center~.center, .right~.right { margin-left: initial; }



/* just a bit of styling */
div { padding: .5rem; }
.left { background: tomato; }
.center { background: orange; }
.right { background: yellowgreen; }
<div class="container">
  <div class="left">Left 1</div>
  <div class="left">Left 2</div>
  <div class="left">Left 3</div>

  <div class="center">Center 1</div>
  <div class="center">Center 2</div>
  <div class="center">Center 3</div>

  <div class="right">Right 1</div>
  <div class="right">Right 2</div>
  <div class="right">Right 3</div>
</div>

Solution 4 :

This does well to maintain the center while still allowing css selectors. It will maintain center adding more elements to the left, middle, or right containers. The middle container can have odd or even elements and it will still maintain center, provided there is adequate room.

The limitations of this approach is that your header height must be fixed, and the absolutely positioned #dynamic_children div top property must reflect that value. Also, due to IE 11’s poor flex implementation, this will not work properly and obviously they will never fix that since IE 11 is no longer supported. I am unsure if that matters for you.

body {
  padding: 0;
  margin: 0;
}

.container {
  display: flex;
  flex-wrap: nowrap;
  height: 30px;
  max-height: 30px;
}

#left_container {
  display: flex;
  justify-content: left;
  flex: 1;
  flex-wrap: nowrap;
  align-items: center;
}

#middle_container {
  display: flex;
  justify-content: center;
  flex: 0;
  flex-wrap: nowrap;
  align-items: center;
}

#right_container {
  display: flex;
  justify-content: right;
  flex: 1;
  flex-wrap: wrap;
  align-items: center;
  margin-left: auto;
}

#check-center {
  display: block;
  width: 100%;
  height: 20px;
  text-align: center;
  background-color: rgb(255, 255, 0);
}

#dynamic_children {
  width: 100%;
  display: block;
  position: absolute;
  top: 30px;
  left: 0;
}

input {
  display: none;
}

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

[ 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;
}
<body>
  <div class="container">
    <div id="left_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>
    </div>
    <div id="middle_container">
      <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>
    </div>
    <div id="right_container">
      <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="dynamic_children">
        <div id="check-center">-|-</div>
        <div>
          <div lang="en">EN selected div 1</div>
          <div lang="fr">FR selected div 1</div>
          <div lang="es">ES selected div 1</div>

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

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

Solution 5 :

As per your requirements, you need to use grid property.

<!DOCTYPE html>
<html>
   <style>
      .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: 12px;
      }
      #check-center {
      width: 100%;
      text-align: center;
      }
      [ lang ] {
      display: none;
      }
      [ name="language" ]:checked+label {
      background-color: pink;
      }
   </style>
   <body>
      <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 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>
   </body>
</html>

Problem :

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?

Comments

Comment posted by Raunaq Patel

Hello, can you explain what are you trying to achieve more? The snippet and explanation still didnt clear it out for me. A simple image will be more helpful. Do you want to show “radiobutton div” on the left, divider in the middle and “language” div on the right? Or do you want to even divide the “radiobutton div” into left middle and right?

Comment posted by Cédric

@RaunaqPatel I added an image

Comment posted by Raunaq Patel

will you be able to wrap inputs into their individual divs? EG left inputs in .left div, center inputs in .center div and so on… Since in your code snippet its all under .Container?

Comment posted by Cédric

No, that is the point of the question

Comment posted by Raunaq Patel

Sorry but I couldnt think about any good way to do this with that restriction. .container > .middle ~ .middle{ margin: unset !important; } .container > .left ~ .middle{ margin-left: auto; } remotely made things centered but then since left items and right items are not there, it couldnt do it

Comment posted by Cédric

It’s a good start, I changed the grid template for

Comment posted by Cédric

Unfortunately

Comment posted by Cédric

Thanks for you answer, maybe it lacks of clarity for this point, I need to access to all

Comment posted by AtomicUs5000

Yes, it would probably help to add left and middle controlled divs to your sample code, even if it has no layout as well as what you just said in this comment.

By