Elements in flexbox aren't receiving equal width

Can't seem to get my flexbox navigation to evenly distribute width among 3-5 items. Need some help figuring it out.

Check out the Fiddle

I found this tutorial that I'm trying to follow: Responsive Fluid Width Variable Item Navigation Tutorial

* {
  font-size: 16px;
}

.tabs {
  max-width: 1010px;
  width: 100%;
  height: 5rem;
  border-bottom: solid 1px grey;
  margin: 0 0 0 6.5rem;
  display: table;
  table-layout: fixed;
}
.tabs ul {
  margin: 0;
  display: flex;
  flex-direction: row;
}
.tabs ul li {
  flex-grow: 1;
  list-style: none;
  text-align: center;
  font-size: 1.313rem;
  background: blue;
  color: white;
  height: inherit;
  left: auto;
  vertical-align: top;
  text-align: left;
  padding: 20px 20px 20px 70px;
  border-top-left-radius: 20px;
  border: solid 1px blue;
  cursor: pointer;
}
.tabs ul li.active {
  background: white;
  color: blue;
}
.tabs ul li:before {
  content: "";
}
<div class="tabs">
  <ul>
    <li class="active" data-tab="1">Pizza</li>
    <li data-tab="2">Chicken Noodle Soup</li>
    <li data-tab="3">Peanut Butter</li>
    <li data-tab="4">Fish</li>
  </ul>
</div>

Answer №1

The article you linked to fails to mention a key detail about the flex-basis property. By default, flex-basis is set to auto.

According to the specification:

If the specified flex-basis is auto, the used flex basis is the value of the flex item’s main size property. (This can itself be the keyword auto, which sizes the flex item based on its contents.)

Each flex item has its own flex-basis, acting as its initial size. The remaining free space is then proportionally distributed among the items based on their flex-grow values. With auto, the basis is determined by the content size (or specified size with width, etc.). Hence, items with larger text content are allocated more space in your specific example.

To ensure equal distribution of space among elements, you can set flex-basis: 0. This will establish a flex basis of 0 and allocate all remaining space proportionally based on the flex-grow property.

li {
    flex-grow: 1;
    flex-basis: 0;
    /* ... */
}

This diagram from the specification effectively illustrates this concept.

For a practical demonstration, check out this working example using your fiddle.

Answer №2

In response to @James Montagne's explanation, setting flex-basis: 0 ensures that the flexbox columns are evenly distributed. This approach works well in situations where the column content can wrap without being constrained by width. However, when the width of the column content is fixed (e.g., with image width or white-space: nowrap), it is recommended to use min-width: 0...

li {
  flex-grow: 1;
  flex-basis: 0;
  min-width: 0;
}

Check out the code example here

Answer №3

If you want to make elements have the same width using Flex, make sure to apply the following properties to your child (flex) elements:

flex-basis: 25%;
flex-grow: 0;

This will ensure that all elements in a row are given 25% width each, without any of them expanding beyond their initial size.

Answer №4

Solution:

flex: 1;

OR

.flex-child-items{
   flex-grow: 1;
} 

Explanation:

In the case where you only have display: flex, the items will align horizontally and their width will be the total of all children's widths (based on content or the width property).

For instance:

// A typical flex arrangement

++++++++++   ++++++++++   ++++++++++
+        +   +        +   +        +
+   A    +   +   B    +   +   C    +
+  10px  +   +  10px  +   +  10px  +
+        +   +        +   +        +
++++++++++   ++++++++++   ++++++++++

If you want to evenly distribute space among them, simply add flex-grow: 1 to each child item within the flex container (A, B, and C in this example).

.A, .B, .C {
    flex-grow: 1;
}

After applying this rule, the layout transforms into:

++++++++++                              ++++++++++                              ++++++++++
+        +                              +        +                              +        +
+   A    +                              +   B    +                              +   C    +
+  10px  +                              +  10px  +                              +  10px  +
+        +                              +        +                              +        +
++++++++++                              ++++++++++                              ++++++++++

*By the way, if the alignment in the above example appears off-center, please test it in your project for accurate results.

Answer №5

To comprehend why the flex-grow property doesn't evenly distribute items in a flex container, we must delve into the mechanics of the flex algorithm and grasp how flex-grow functions.

  1. Originary Behavior of display:flex:

Upon setting a container to display:flex, it defaults to flex-direction:row, causing its flex items to have widths determined by their content. In this scenario, larger content results in wider items. The removal of padding and flex-grow from your code highlights this behavior:

After clearing those declarations from .tabs ul li:{...}:

flex-grow: 1;
padding: 20px 20px 20px 70px;

https://i.sstatic.net/bhBuK.png

* {
  font-size: 16px;
}

.tabs {
  max-width: 1010px;
  width: 100%;
  height: 5rem;
  border-bottom: solid 1px grey;
  margin: 0 0 0 6.5rem;
  display: table;
  table-layout: fixed;
}
.tabs ul {
  margin: 0;
  display: flex;
  flex-direction: row;
}
.tabs ul li {
/*   flex-grow: 1; */
  list-style: none;
  text-align: center;
  font-size: 1.313rem;
  background: blue;
  color: white;
  height: inherit;
  left: auto;
  vertical-align: top;
  text-align: left;
/*   padding: 20px 20px 20px 70px; */
  border-top-left-radius: 20px;
  border: solid 1px blue;
  cursor: pointer;
}
.tabs ul li.active {
  background: white;
  color: blue;
}
.tabs ul li:before {
  content: "";
}
<div class="tabs">
  <ul>
    <li class="active" data-tab="1">Pizza</li>
    <li data-tab="2">Chicken Noodle Soup</li>
    <li data-tab="3">Peanut Butter</li>
    <li data-tab="4">Fish</li>
  </ul>
</div>

2. The Function of flex-grow: When applied to a flex item, flex-grow commands the item to expand when there's available space within the container.

3. Even Distribution with flex-grow:1: By setting all items to flex-grow:1, as demonstrated in your example, they will share the remaining space proportionally. However, initially, they do not have equal widths. The additional space is distributed among each item based on its initial width (the content width).

This is how it appears when reverting back to flex-grow:1:

Note that while the right space after each item is uniform, the item widths are unequal due to varying content sizes https://i.sstatic.net/pl9qi.png

4. Resolving the Uneven Width Concern: To achieve genuine equal distribution, you can set the width of the items to 0, allowing the space to be allocated by flex-grow resulting in this appearance: https://i.sstatic.net/chqqz.png

Take note of the blue rectangle outlining all items

With all available space now accessible for distribution by flex-grow, it can be evenly divided among the flex items.

Alternatively, utilizing the flex-basis property ensures equal distribution. Setting flex-basis:0 yields a similar outcome. Another option involves employing the shorthand flex property, where flex:1 mirrors flex-grow:1, flex-shrink:1, and flex-basis:0.

Both approaches yield equivalent results:

https://i.sstatic.net/eztz7.png

Following the reintroduction of padding, here is the resultant depiction: https://i.sstatic.net/mru2m.png

The flex algorithm determines the original width (for flex-direction:row) and height (for flex-direction:column) using flex-basis, which can supersede the width or height property if present. To prevent potential errors, it is advisable to utilize it or the shorthand flex property to ensure consistent and predictable performance.

In conclusion, guaranteeing equitable space distribution among flex items is achievable through flex-basis:0 or flex:1 with default values while acknowledging the intricacies of the flex algorithm. This approach maintains an equal and consistent division of items within a flex container, regardless of their initial content-based widths.

Answer №6

Flex sometimes doesn't distribute widths equally among its children.

To achieve equal width elements, consider using CSS grid instead.

.el{
 display: grid;
 grid-auto-flow: column;
 grid-auto-columns: 1fr
}

For further information, visit https://css-tricks.com/equal-columns-with-flexbox-its-more-complicated-than-you-might-think/

If you prefer to stick with CSS flex alone, there are a couple of options:

  1. flex-basis: 100% for all child elements can provide a close match. OR
  2. flex-basis: 0, although less effective than the first option.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

numerous requirements for formatting utilizing Css modules

Can someone help me figure out how to set multiple conditions using a ternary operator to style an element with Css modules? I'm struggling to find the right syntax. Is it even possible? import style from './styles.module.sass' const Slider ...

Issue with CSS3 animation in Chrome: @keyframes not incorporating transition

Below is the code I'm using for my animation: <div id="slider" style="width: 230px; height: 150px; padding:5px"> <div id="mask"> <ul style="list-style:none;"> <li class='firstAnimation'> ...

What could be preventing my XPath from selecting a link/button using its label text?

<a href="javascript:void(0)" title="home"> <span class="menu_icon">Possibly more content could go here</span> Home </a> When I use //a as the XPath in the above code, it is highlighted. However, when I try //a[contains(text ...

JavaScript allows for selecting individual IDs by their corresponding numbers

Looking to retrieve numerical IDs <div class="user-view"> <div class="show_user_div"> <div class="disp"> <a href="/profile/name1/">name1</a><br /> <span id="show_a_3"> <a id="ref_show(3)">Show Details</ ...

Safeguarding replicated HTML tags within a Python dictionary during web scraping with Beautiful Soup 4

Utilizing BeautifulSoup4 in Python 3.6, I am extracting data from a website where some content is structured like this: <div class="contentContainer"> <p class="contentLabel">Living Room</p> <span class="contentValue">15 m ...

What is the best way to identify the appropriate element to display based on the anchor inside the element?

Incorporating various Twitter Bootstrap collapse groups on my website is a key feature. These groups consist of multiple anchors: <div class="accordion" id="accordion"> <div class="accordion-group"> <div class="accordion-heading" ...

JSON will soon be receiving an Angular directive

Having a directive: This data object is passed: <a-link options = "data"></a-link> Here's the code for my directive: .directive('aLink', function() { return { restrict: 'AE', replace: true, template: ...

Change the display of the current page by clicking a form button

Apologies, I am new to jsp and have limited knowledge of html. My goal is to create a form button that takes input from a form and uses it in an SQL query. When the button is pressed, I want a table with the results of the query to appear. I have some exa ...

What is the best way to trigger a javascript modal to open automatically after a specific duration

Let's take an instance where my modal has the ID #modal1. It usually appears through a button-based action. ...

What steps should I take to modify my navigation menu to display 'Logout' once a user is logged in?

I'm currently working on a small project to create a basic website and I am struggling with implementing a feature in PHP that changes the menu navbar to "Logout" once the user has successfully signed in. Below, you can find the navbar code as well a ...

Tips for repairing buttons in the CSS container

The buttons in the CSS search-box are not staying fixed as intended. They should be within the search box, but instead, they are protruding out of the panel. I attempted to utilize z-index, but it did not produce the desired outcome. https://i.sstatic.n ...

Experiencing a problem when attempting to activate the html5 mode feature in AngularJS to eliminate the #

I've been scouring through various sources like stackoverflow and the web, but I haven't found a clear answer to my question. Can someone please help me out? Here's what I'm struggling with: In my AngularJS application, I enabled &apos ...

jQuery method for implementing alternating row colors that are not sequential

Starting from scratch here. I've fetched a table from a remote server where odd rows are white and even rows are grey. Some rows have been hidden: $("td").filter(function(){ return $(this).text()=='R1';}).text('Row1'); //white $(" ...

Changing the background color using jQuery switch case statement

I am attempting to utilize jquery to dynamically change the background image of a webpage based on different cases in a JavaScript switch statement. I have completed three steps: 1) Included this script tag in my HTML document: <script src="http://co ...

Using the div tag will result in a new line being created

Whenever I try to create an element with a div, I notice there is always some space between the content and the border (blue line). On the other hand, using span causes the content to break, appearing outside the borders. Here is my CSS code: #m ...

Using the display property of inline-block in conjunction with PHP will lead to unexpected results (see screenshots provided)

I am in the process of developing an online store using PHP/SQL to showcase product information. I have applied a display: inline-block in the CSS, and it functions properly without PHP. However, when PHP is added, it seems to switch to a display: block e ...

Visual Delights on the Menu

I am having trouble adding a "Home" picture to my menu. It keeps showing up as a blank square, even though I have tried using both .png and .jpg formats. Here is the code that I am currently using: <div id='cssmenu'> <link rel= ...

Overflow of content from `div` on top of the window

I have a section with tabs, each tab displaying different content. One of those tabs contains a table taller than the screen size. When I open it, the section stretches and overflows from the top, extending beyond the window. Despite having overflow:auto s ...

Attempting to isolate SQL outcome in order to adjust price based on a percentage

I am currently working on a SQL search and results page that displays 3 columns of data: category, number, and price. However, the results are returned all together in one big lump. My goal is to have a dropdown list with percentages, where clicking on one ...

Utilize jQuery to locate a specific value within a collapsible Bootstrap 4 table

Is it possible to use a Bootstrap 4 table inside a collapse? I need to search for a specific value in the table and if the value is found, I want to open the collapse and display the row containing that value. <div id="collapseStudents" class="collapse ...