<header class="header">
  <form class="settings">
    <fieldset class="col-left">
      <label for="adjustedColumnWidth" class="grid-style">
        <input type="radio" checked name="grid-style" value="adjusted-column-width" id="adjustedColumnWidth" class="grid-style"></input>
        Adjusted columns width
      </label>
      <label for="fixedColumnWidth" class="grid-style">
        <input type="radio" name="grid-style" value="fixed-column-width" id="fixedColumnWidth" class="grid-style"></input>
        Fixed columns width
      </label>
    </fieldset>
    <fieldset class="col-right">
      <div class="input-range-wrapper">
        <label for="maxCols">
          Maximum columns number
        </label>
        <div class="input-wrapper">
          <input type="range" id="maxCols" class="cols-number max-cols" min="1" max="10"></input>
          <output class="output"></output>
        </div>
      </div>
      <div class="input-range-wrapper">
        <label for="minCols">
          Minimum columns number
        </label>
        <div class="input-wrapper">
          <input type="range" id="minCols" class="cols-number min-cols" min="1" max="10"></input>
          <output class="output"></output>
        </div>
      </div>
      <div class="input-range-wrapper">
        <label for="colsMinWidth">
          Columns min width
        </label>
        <div class="input-wrapper">
          <input type="range" id="colsMinWidth" class="cols-min-width" min="0" max="200"></input>
          <output class="output"></output>
        </div>
      </div>
    </fieldset>
  </form>
  <section class="info">
    <p class="text">You can resize the with of the container from the bottom right corner</p>
    <button id="toggleSettings" class="toggle-settings hide-settings"></button>
  </section>
</header>

<main class="content">
  <section class="resize">
    <h2>justify-content: center</h2>
    <div class="parent center parent--adjusted-width">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>

    <h2>justify-content: space-between</h2>
    <div class="parent between parent--adjusted-width">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>

    <h2>justify-content: space-evenly</h2>
    <div class="parent evenly parent--adjusted-width">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>

    <h2>justify-content: space-around</h2>
    <div class="parent around parent--adjusted-width">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>
  </section>
</main>
/* The magic */
/* Mixins for defining a grid with min and max columns */

/* Adjusted columns width */
@mixin grid-cols-adjusted($min-cols, $max-cols, $cols-min-width, $row-gap: 0px, $col-gap: 0px) {
  --min-cols: #{$min-cols};
  --max-cols: #{$max-cols};
  --cols-min-width: #{$cols-min-width};
  --row-gap: #{$row-gap};
  --col-gap: #{$col-gap};
  
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min((100%/var(--min-cols) - var(--col-gap)*(var(--min-cols) - 1)/var(--min-cols)), max(var(--cols-min-width), (100%/var(--max-cols) - var(--col-gap)*(var(--max-cols) - 1)/var(--max-cols)))), 1fr));
  gap: var(--row-gap) var(--col-gap);
}

/* Fixed columns width */
@mixin grid-cols-fixed($min-cols, $max-cols, $cols-min-width, $row-gap: 0px, $col-gap: 0px) {
  --min-cols: #{$min-cols};
  --max-cols: #{$max-cols};
  --cols-min-width: #{$cols-min-width};
  --row-gap: #{$row-gap};
  --col-gap: #{$col-gap};
  
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, min((100%/var(--min-cols) - var(--col-gap)*(var(--min-cols) - 1)/var(--min-cols)), max(var(--cols-min-width), (100%/var(--max-cols) - var(--col-gap)*(var(--max-cols) - 1)/var(--max-cols))))));
  gap: var(--row-gap) var(--col-gap);
}

.parent {
  /* Set styles to see the parent */
  padding: 1rem 0;
  border: 3px solid dodgerblue;
  border-radius: 5px;
  background: wheat;
  
  /* Grid systems */
  $min-cols: 3;
  $max-cols: 7;
  $cols-min-width: 7.5rem;
  $row-gap: 1.5rem;
  $col-gap: 1rem;
  &--adjusted-width {
    @include grid-cols-adjusted($min-cols, $max-cols, $cols-min-width, $row-gap, $col-gap);
  }
  &--fixed-width {
    @include grid-cols-fixed($min-cols, $max-cols, $cols-min-width, $row-gap, $col-gap);
  }
  
  &.center {
    justify-content: center;
  }
  &.between {
    justify-content: space-between;
  }
  &.evenly{
    justify-content: space-evenly;
  }
  &.around {
    justify-content: space-around;
  }
}

.child {
  min-height: 3.125rem;
  padding: .3125rem 0;
  border: 2px solid brown;
  border-radius: 5px;
}

/* Styles not related to the goal */
html {
	box-sizing: border-box;
  height: 100%;
  
  @media (max-height: 22.5rem) {
    font-size: 55%;
  }
}
*, 
*:before, *:after {
	box-sizing: inherit;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  display: flex;
  flex-direction: column;
}

header,
main {
  text-align: center;
}

h2 {
  margin-bottom: .2rem
}

fieldset,
input {
  margin: 0;
  padding: 0;
}

.header {
  .settings {
    padding: .5rem;
    font-weight: bold;
    background: darksalmon;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    column-gap: 2rem;
    row-gap: 1rem;

    &.is-hidden {
      display: none;
    }

    .col-left,
    .col-right {
      display: flex;
      flex-direction: column;
      gap: .5rem;
      border: none;
      text-align: left;
    }
    
    .col-left {
      label {
        display: flex;
        align-items: center;
        gap: .5rem;
      }
    }

    .input-range-wrapper {
      display: flex;
      flex-direction: column;
      gap: .25rem;

      .input-wrapper {
        display: flex;
        align-items: center;
        gap: .5rem;
      }
    }
    
    .cols-min-width + .output {
      min-width: 6ch;
    }
  }

  .info {
    display: flex;
    justify-content: center;
    align-items: center;
    color: white;
    margin: 0;
    padding: .5rem;
    background: #777;
    
    .text {
      flex: 1 0 10rem;
      font-weight: bold;
      margin: 0;
      padding: 0 1rem;
    }

    .toggle-settings {
      display: flex;
      align-items: center;
      gap: .5rem;
      font-size: inherit;
      color: white;
      background: none;
      border: none;
      border-left: 2px solid white;
      cursor: pointer;

      &::before {
        content: "▼";
        display: inline-block;
        transition: transform .5s ease .3s;
      }
      &::after {
        content: "Show settings";
        font-size: .9em;
      }
      
      &.hide-settings {
        &::before {
          transform: rotate(180deg);
        }
        &::after {
          content: "Hide settings"
        }
      }
    }
    
    @media (max-width: 22.5rem) {
      flex-direction: column;
      gap: .5rem;
      
      .text {
        flex: 1;
      }
      
      .toggle-settings {
        padding-top: .4rem;
        border-left: none;
        border-top: 2px solid white;
      }
    }
  }
}

.content {
  flex: 1;
  width: 75%;
  max-width: 100%;
  margin: auto;
  padding: 1rem;
  overflow: auto;
  resize: horizontal;
  background-image: linear-gradient(white, lightgray);
}
View Compiled
const parentElements = document.querySelectorAll(".parent");
const gridStyleInput = document.querySelectorAll(".grid-style");
let gridStyle;

gridStyleInput.forEach(input => {
  input.addEventListener("input", () => {
    if (input.checked) {
      gridStyle = input.value;
    }
    if (gridStyle === "adjusted-column-width") {
      parentElements.forEach(parent => {
        parent.classList.remove("parent--fixed-width");
        parent.classList.add("parent--adjusted-width");
      })
    }
    if (gridStyle === "fixed-column-width") {
      parentElements.forEach(parent => {
        parent.classList.remove("parent--adjusted-width");
        parent.classList.add("parent--fixed-width");
      })
    }
  });
});

const maxColsInput = document.getElementById("maxCols");
const maxColsOutput = document.querySelector("#maxCols + .output");
maxColsInput.value = +getComputedStyle(parentElements[0]).getPropertyValue("--max-cols");

maxColsInput.addEventListener("input", () => {
  setMaxCols();
});

const minColsInput = document.getElementById("minCols");
const minColsOutput = document.querySelector("#minCols + .output");
minColsInput.value = +getComputedStyle(parentElements[0]).getPropertyValue("--min-cols");

minColsInput.addEventListener("input", () => {
  setMinCols();
});

const colsMinWidthInput = document.getElementById("colsMinWidth");
const colsMinWidthOutput = document.querySelector("#colsMinWidth + .output");
colsMinWidthInput.value = getColsMinWidthValue();

function getColsMinWidthValue() {
  let value;
  const colsMinWidthValue = getComputedStyle(parentElements[0]).getPropertyValue("--cols-min-width");
  const colsMinWidthLowerCase = colsMinWidthValue.toLowerCase();
  if (colsMinWidthLowerCase.includes("rem")) {
    const colsMinWidthNumeric = +colsMinWidthLowerCase.replace("rem", "");
    value = colsMinWidthNumeric * parseFloat(getComputedStyle(document.documentElement).fontSize);
  } else if (colsMinWidthLowerCase.includes("%")) {
    const colsMinWidthNumeric = +colsMinWidthLowerCase.replace("%", "");
    const parentWidth = document.querySelector(".parent").offsetWidth;
    value = colsMinWidthNumeric * parentWidth / 100;
  } else if (colsMinWidthLowerCase.includes("px")) {
    const colsMinWidthNumeric = +colsMinWidthLowerCase.replace("rem", "");
    value = colsMinWidthNumeric;
  }
  if (!value) {
    alert("The 3rd parameter for the mixins (min-cols-width) should be set in 'rem', '%' or 'px' units");
  return 100;
  }
  if (value < 0 || value > 200) {
    alert("The 3rd parameter for the mixins (min-cols-width) must be between 0 and 200 pixels");
  return 100;
  }
  return value;
}

colsMinWidthInput.addEventListener("input", () => {
  setColsMinWidth();
});

function setMaxCols() {
  parentElements.forEach(parent => {
    parent.style.setProperty('--max-cols', maxColsInput.value);
    maxColsOutput.innerText = maxColsInput.value;
  });
  if (+maxColsInput.value < +minColsInput.value) {
    minColsInput.value = maxColsInput.value;
    setMinCols();
  }
}

setMaxCols();

function setMinCols() {
  parentElements.forEach(parent => {
    parent.style.setProperty('--min-cols', minColsInput.value);
    minColsOutput.innerText = minColsInput.value;
  });
  if (+minColsInput.value > +maxColsInput.value) {
    maxColsInput.value = minColsInput.value;
    setMaxCols();
  }
}

setMinCols();

function setColsMinWidth() {
  parentElements.forEach(parent => {
    parent.style.setProperty('--cols-min-width', colsMinWidthInput.value+"px");
    colsMinWidthOutput.innerText = colsMinWidthInput.value+"px";
  });
}

setColsMinWidth();

const settings = document.querySelector(".settings");
const toggleSettingsButton = document.getElementById("toggleSettings");

toggleSettingsButton.addEventListener("click", () => {
  settings.classList.toggle("is-hidden");
  toggleSettingsButton.classList.toggle("hide-settings");
})
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.