Search code examples
htmlcssflexboxmedia-queriesresponsive

Centre aligning elements with CSS flex


I've set up my code using flex so that it works responsively (it's looking how I'd like on devices sub 960 in width so any changes to desktop happen within the css query at the bottom of my CSS file). potentially a very simple question but on views wider than 960 the 8 tiles aren't a consistent width (one .row containing 4 .tiles) - I tried adding a width of 25% which I thought would make them always evenly span the width of the page but that didn't work. Within that the .content (expanding content) seems to extend further that the row to the right which I cant understand?

any ideas would be really appreciated!

working fiddle: https://jsfiddle.net/simoncunningham/zsLxuo26/7/

any advice would appreciated!

<div class="box">
      <div class="tile" onclick="openTab('b1');">
        <img class="icon-spacing" src="./Icons/Banking.svg" />
        <p>Banking</p>
        <img class="arrow-down" src="./Icons/arrow-down.png" />
      </div>
      <div id="b1" class="content" style="display: none; background: black">
        <span onclick="this.parentElement.style.display='none'" class="closebtn"
          >&times;</span
        >
        <div class="description">
          <h3>Banking</h3>
          <p>
            The largest category covering investment and management platforms,
            sales and trading analysis toosl, personal finance management &
            crypto exchanges.
          </p>
          <ul>
            <li>Personal Finance Management (PFM)</li>
            <li>Investment Data and Information Services</li>
            <li>Trading and Investment Platforms</li>
            <li>WealthTech Operations</li>
            <li>Distributed Ledger Technologies & Cryptocurrencies</li>
            <li>Robo Advisors</li>
          </ul>
        </div>
      </div>
      <div class="tile" onclick="openTab('b2');">
        <img class="icon-spacing" src="./Icons/RegTech.svg" />
        <p>RegTech</p>
        <img class="arrow-down" src="./Icons/arrow-down.png" />
      </div>
      <div id="b2" class="content" style="display: none; background: black">
        <span onclick="this.parentElement.style.display='none'" class="closebtn"
          >&times;</span
        >
        <div class="description">
          <h3>RegTech</h3>
          <p>
            The largest category covering investment and management platforms,
            sales and trading analysis toosl, personal finance management &
            crypto exchanges.
          </p>
          <ul>
            <li>Personal Finance Management (PFM)</li>
            <li>Investment Data and Information Services</li>
            <li>Trading and Investment Platforms</li>
            <li>WealthTech Operations</li>
            <li>Distributed Ledger Technologies & Cryptocurrencies</li>
            <li>Robo Advisors</li>
          </ul>
        </div>
      </div>
      <div class="tile" onclick="openTab('b3');">
        <img class="icon-spacing" src="./Icons/InsurTech.svg" />
        <p>InsurTech</p>
        <img class="arrow-down" src="./Icons/arrow-down.png" />
      </div>
      <div id="b3" class="content" style="display: none; background: black">
        <span onclick="this.parentElement.style.display='none'" class="closebtn"
          >&times;</span
        >
        <div class="description">
          <h3>InsurTech</h3>
          <p>
            The largest category covering investment and management platforms,
            sales and trading analysis toosl, personal finance management &
            crypto exchanges.
          </p>
          <ul>
            <li>Personal Finance Management (PFM)</li>
            <li>Investment Data and Information Services</li>
            <li>Trading and Investment Platforms</li>
            <li>WealthTech Operations</li>
            <li>Distributed Ledger Technologies & Cryptocurrencies</li>
            <li>Robo Advisors</li>
          </ul>
        </div>
      </div>
      <div class="tile" onclick="openTab('b4');">
        <img class="icon-spacing" src="./Icons/Lending.svg" />
        <p>Lending</p>
        <img class="arrow-down" src="./Icons/arrow-down.png" />
      </div>
      <div id="b4" class="content" style="display: none; background: black">
        <span onclick="this.parentElement.style.display='none'" class="closebtn"
          >&times;</span
        >
        <div class="description">
          <h3>Lending</h3>
          <p>
            The largest category covering investment and management platforms,
            sales and trading analysis toosl, personal finance management &
            crypto exchanges.
          </p>
          <ul>
            <li>Personal Finance Management (PFM)</li>
            <li>Investment Data and Information Services</li>
            <li>Trading and Investment Platforms</li>
            <li>WealthTech Operations</li>
            <li>Distributed Ledger Technologies & Cryptocurrencies</li>
            <li>Robo Advisors</li>
          </ul>
        </div>
      </div>
    </div>

    <div class="box">
      <div class="tile" onclick="openTab('b5');">
        <img class="icon-spacing" src="./Icons/Accounting.svg" />
        <p>Accounting</p>
        <img class="arrow-down" src="./Icons/arrow-down.png" />
      </div>
      <div id="b5" class="content" style="display: none; background: black">
        <span onclick="this.parentElement.style.display='none'" class="closebtn"
          >&times;</span
        >
        <div class="description">
          <h3>Accounting</h3>
          <p>
            The largest category covering investment and management platforms,
            sales and trading analysis toosl, personal finance management &
            crypto exchanges.
          </p>
          <ul>
            <li>Personal Finance Management (PFM)</li>
            <li>Investment Data and Information Services</li>
            <li>Trading and Investment Platforms</li>
            <li>WealthTech Operations</li>
            <li>Distributed Ledger Technologies & Cryptocurrencies</li>
            <li>Robo Advisors</li>
          </ul>
        </div>
      </div>
      <div class="tile" onclick="openTab('b6');">
        <img class="icon-spacing" src="./Icons/Payments.svg" />
        <p>Payments</p>
        <img class="arrow-down" src="./Icons/arrow-down.png" />
      </div>
      <div id="b6" class="content" style="display: none; background: black">
        <span onclick="this.parentElement.style.display='none'" class="closebtn"
          >&times;</span
        >
        <div class="description">
          <h3>Payments</h3>
          <p>
            The largest category covering investment and management platforms,
            sales and trading analysis toosl, personal finance management &
            crypto exchanges.
          </p>
          <ul>
            <li>Personal Finance Management (PFM)</li>
            <li>Investment Data and Information Services</li>
            <li>Trading and Investment Platforms</li>
            <li>WealthTech Operations</li>
            <li>Distributed Ledger Technologies & Cryptocurrencies</li>
            <li>Robo Advisors</li>
          </ul>
        </div>
      </div>
      <div class="tile" onclick="openTab('b7');">
        <img class="icon-spacing" src="./Icons/Quote.svg" />
        <p>Quote</p>
        <img class="arrow-down" src="./Icons/arrow-down.png" />
      </div>
      <div id="b7" class="content" style="display: none; background: black">
        <span onclick="this.parentElement.style.display='none'" class="closebtn"
          >&times;</span
        >
        <div class="description">
          <h3>Quote</h3>
          <p>
            The largest category covering investment and management platforms,
            sales and trading analysis toosl, personal finance management &
            crypto exchanges.
          </p>
          <ul>
            <li>Personal Finance Management (PFM)</li>
            <li>Investment Data and Information Services</li>
            <li>Trading and Investment Platforms</li>
            <li>WealthTech Operations</li>
            <li>Distributed Ledger Technologies & Cryptocurrencies</li>
            <li>Robo Advisors</li>
          </ul>
        </div>
      </div>
      <div class="tile" onclick="openTab('b8');">
        <img class="icon-spacing" src="./Icons/WealthTech.svg" />
        <p>WealthTech</p>
        <img class="arrow-down" src="./Icons/arrow-down.png" />
      </div>
      <div id="b8" class="content" style="display: none; background: black">
        <span onclick="this.parentElement.style.display='none'" class="closebtn"
          >&times;</span
        >
        <div class="description">
          <h3>WealthTech</h3>
          <p>
            The largest category covering investment and management platforms,
            sales and trading analysis toosl, personal finance management &
            crypto exchanges.
          </p>
          <ul>
            <li>Personal Finance Management (PFM)</li>
            <li>Investment Data and Information Services</li>
            <li>Trading and Investment Platforms</li>
            <li>WealthTech Operations</li>
            <li>Distributed Ledger Technologies & Cryptocurrencies</li>
            <li>Robo Advisors</li>
          </ul>
        </div>
      </div>
    </div>
body {
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
}

.box {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
}

.tile {
  flex: 1 0 auto;
  order: 0;

  /* For visual only  */
  background-color: black;
  border: 1px solid grey;
  height: 150px;
  text-align: center;
  font-size: 16px;
  color: white;
  cursor: pointer;
}

.active-tile {
  flex: 1 0 auto;
  order: 0;

  /* For visual only  */
  text-align: center;
  border: 1px solid #000;
  background-color: green;
  height: 125px;
  cursor: pointer;
}

.content {
  order: 1;
  flex: 1 0 100%;

  /* For visual only  */
  padding: 20px;
  color: white;
  text-align: center;
  border: 1px solid #000;
  background-color: #228b22;
}

.description {
  text-align: left;
}

.icon-spacing {
  margin-top: 24px;
}

/* Clear floats after the tiles */
.box:after {
  content: '';
  display: table;
  clear: both;
}

.closebtn {
  float: right;
  color: white;
  cursor: pointer;
}

.arrow-down {
  width: 25px;
  height: 25px;
}

.arrow-up {
  width: 25px;
  height: 25px;
  -webkit-transform: rotate(180deg);
  -moz-transform: rotate(180deg);
  -ms-transform: rotate(180deg);
  -o-transform: rotate(180deg);
  transform: rotate(180deg);
}

/* 
  "Desktop" and above
 */
@media (max-width: 961px) {
  .box {
    flex-direction: column;
  }

  .content {
    order: 0;
  }
}

 function openTab(tabName) {
        var i, x;
        x = document.getElementsByClassName('content');
        for (i = 0; i < x.length; i++) {
          x[i].style.display = 'none';
        }
        document.getElementById(tabName).style.display = 'block';

        // Get all the tabs into a collection
        // (don't use .getElementsByClassName()!)
        let tabs = document.querySelectorAll('.tile');

        // Set up a click event handler on each of the tabs
        tabs.forEach(function (tab) {
          tab.addEventListener('click', function (event) {
            // Loop over all the tabs and remove the active class
            tabs.forEach(function (tab) {
              tab.classList.remove('active-tile');
              tab.children[2].classList.remove('arrow-up');
            });

            // Set the background of the clicked tab
            this.classList.add('active-tile');
            tab.children[2].classList.add('arrow-up');
          });
        });
      }

Solution

  • Your problem (when you try width: 25% on tiles) is that 100% is calculated without taking into account the border and the padding.

    • .tile has a border of 1px, so 25% * 4 + 8 * 1px is more than 100%.
    • .content has a border of 1px, and a padding of 20px, so 100% + 2 * 1px + 2 * 20px is more than 100%.

    To solve the issue you can just change the way your box is calculated by including the border and the padding when you assign the width:

    .tile, .content {
      box-sizing: border-box;
    }
    
    .tile {
      width: 25%;
    }
    

    You can learn more about box-sizing and its values on the MDN documentation page.