Search code examples
htmlcssflexbox

Div does not have the expected width based on percentage of container


I have a .section-offerings section in my html file, inside I have 2 divs that will be rows in a table of features about a product. Each row is supposed to have an icon and a description of the feature, I added two divs for icon and description. This is the idea:

enter image description here

I set the section max-width to 1000px, and then set the icon divs classes to width 20%. I expected both divs to be 200px... but only the first one is. As you can see in the image the text of both rows is not aligned, and this is because the icon div has different sizes.

Can someone explain to me why this happens? I expected 200px for both, since it is the 20% of the container.

Here is my code as reference. I am totally new on this, just learning!

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

body {
  width: 100%;
  min-height: 100vh;
  background-color: #eee;
  font-family: 'Lato', sans-serif;
  margin-top: 75px;
}

.section-offerings {
  max-width: 1000px;
  margin: 0 auto;
}

.offerings-row {
  display: flex;
  align-items: center;
}

.offerings-icon {
  width: 20%;
  height: 125px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: darkorange;
}
<main>
  <section class="section-offerings">
    <div class="offerings-row">
      <div class="offerings-icon"><i class="fa fa-3x fa-fire"></i></div>
      <div class="offerings-desc">
        <h2>Premium Materials</h2>
        <p>Our trombones use the shiniest brass which is sourced locally. This will increase the longevity of your purchase.</p>
      </div>
    </div>
    <div class="offerings-row">
      <div class="offerings-icon"><i class="fa fa-3x fa-truck"></i></div>
      <div class="offerings-desc">
        <h2>Fast Shipping</h2>
        <p>We make sure you recieve your trombone as soon as we have finished making it. We also provide free returns if you are not satisfied.</p>
      </div>
    </div>
  </section>
</main>

I tried using vw units instead of percentage, but the outcome is the same.


Solution

  • if you want to set the width of each .offerings-icon class to 200px, there are a few ways to achieve that. It depends on whether you need the .section-offerings container to be exactly 1000px wide. If so, follow these steps:

    • Set width: 1000px instead of max-width: 1000px for the .section-offerings class;
    • Add the rule flex-shrink: 0 to the .offerings-icon class.

    Here's an example:

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      width: 100%;
      min-height: 100vh;
      background-color: #eee;
      font-family: 'Lato', sans-serif;
      margin-top: 75px;
    }
    
    .section-offerings {
      width: 1000px;
      margin: 0 auto;
    }
    
    .offerings-row {
      display: flex;
      align-items: center;
    }
    
    .offerings-icon {
      width: 20%;
      height: 125px;
      display: flex;
      justify-content: center;
      align-items: center;
      color: darkorange;
      flex-shrink: 0;
    }
    <main>
      <section class="section-offerings">
        <div class="offerings-row">
          <div class="offerings-icon"><i class="fa fa-3x fa-fire"></i></div>
          <div class="offerings-desc">
            <h2>Premium Materials</h2>
            <p>Our trombones use the shiniest brass which is sourced locally. This will increase the longevity of your purchase.</p>
          </div>
        </div>
        <div class="offerings-row">
          <div class="offerings-icon"><i class="fa fa-3x fa-truck"></i></div>
          <div class="offerings-desc">
            <h2>Fast Shipping</h2>
            <p>We make sure you recieve your trombone as soon as we have finished making it. We also provide free returns if you are not satisfied.</p>
          </div>
        </div>
      </section>
    </main>

    If you need to keep the max-width for your .section-offerings class, it means your whole container can be a maximum of 1000px wide. However, the minimum width will depend on the inner content or the parent container (in your case, it's the element). This approach is more popular because it allows more flexible control over your elements on the page, depending on the screen width (mobile, tablet, desktop versions).

    If you need to set the width of your .offerings-icon class to 200px. The rule width: 20% is not suitable because your parent container can have varying widths, ranging from the minimum content width up to 1000px. When you set 20% for a child element, it means it will take 20% of the parent width. If your parent container is 600px wide, the child element will be 120px wide (20% of 600px). You can test it in Developer Tools and inspect the element's width.

    If you need the width of your .offerings-icon class to be 20% of the parent container but don't need it to be exactly 200px, you should set flex-shrink: 0 for the .offerings-icon class. This rule will fix the issue where your .offerings-icon has varying widths.

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      width: 100%;
      min-height: 100vh;
      background-color: #eee;
      font-family: 'Lato', sans-serif;
      margin-top: 75px;
    }
    
    .section-offerings {
      max-width: 1000px;
      margin: 0 auto;
    }
    
    .offerings-row {
      display: flex;
      align-items: center;
    }
    
    .offerings-icon {
      width: 20%;
      height: 125px;
      display: flex;
      justify-content: center;
      align-items: center;
      color: darkorange;
      flex-shrink: 0;
    }
    <main>
      <section class="section-offerings">
        <div class="offerings-row">
          <div class="offerings-icon"><i class="fa fa-3x fa-fire"></i></div>
          <div class="offerings-desc">
            <h2>Premium Materials</h2>
            <p>Our trombones use the shiniest brass which is sourced locally. This will increase the longevity of your purchase.</p>
          </div>
        </div>
        <div class="offerings-row">
          <div class="offerings-icon"><i class="fa fa-3x fa-truck"></i></div>
          <div class="offerings-desc">
            <h2>Fast Shipping</h2>
            <p>We make sure you recieve your trombone as soon as we have finished making it. We also provide free returns if you are not satisfied.</p>
          </div>
        </div>
      </section>
    </main>

    The last option: if you still need the .offerings-icon element to be exactly 200px wide, simply apply the rule flex: 0 0 200px; to your .offerings-icon class and remove width: 20%;.

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      width: 100%;
      min-height: 100vh;
      background-color: #eee;
      font-family: 'Lato', sans-serif;
      margin-top: 75px;
    }
    
    .section-offerings {
      max-width: 1000px;
      margin: 0 auto;
    }
    
    .offerings-row {
      display: flex;
      align-items: center;
    }
    
    .offerings-icon {
      height: 125px;
      display: flex;
      justify-content: center;
      align-items: center;
      color: darkorange;
      flex: 0 0 200px;
    }
    <main>
      <section class="section-offerings">
        <div class="offerings-row">
          <div class="offerings-icon"><i class="fa fa-3x fa-fire"></i></div>
          <div class="offerings-desc">
            <h2>Premium Materials</h2>
            <p>Our trombones use the shiniest brass which is sourced locally. This will increase the longevity of your purchase.</p>
          </div>
        </div>
        <div class="offerings-row">
          <div class="offerings-icon"><i class="fa fa-3x fa-truck"></i></div>
          <div class="offerings-desc">
            <h2>Fast Shipping</h2>
            <p>We make sure you recieve your trombone as soon as we have finished making it. We also provide free returns if you are not satisfied.</p>
          </div>
        </div>
      </section>
    </main>