Exploring the depths of CSS table-cell and the impact of percentage-based

During my exploration of Github, I came across a fascinating menu display:

If you pay attention, each item in the menu is assigned an equal width. In CSS, we typically give it a percentage value - but why? It's interesting to note that the parent div does not have the display: table property.

div {
  border: 1px solid #000;
  border-radius: 4px;
}

div ul {
  padding: 0;
  margin: 0;
}

div ul li {
  display: table-cell;
  width: 1%;
  text-align: center;
  border-right: 1px solid #000;
  padding: 10px 0;
}

div ul li:last-child {
  border-right: 0;
}
<div>
  <ul>
    <li><a href="#">Commits</a>
    </li>
    <li><a href="#">Branch</a>
    </li>
    <li><a href="#">Contribution</a>
    </li>
    <li><a href="#">anything</a>
    </li>
  </ul>
</div>

Have you ever wondered about the rationale behind using percentage width?

Answer №1

Understanding how automatic table layout functions is crucial here. Specifically:

When a column width is set as a percentage, it is relative to the table width. If the table's width is set to 'auto', the percentage serves as a guideline for the column width that the browser will attempt to fulfill. However, if a column width is set to '110%', for example, this guideline cannot be met.

In your scenario, tiny percentage widths are applied to each table-cell element. The browser must ensure that these cells fill the entire width of the table (which matches its containing block), leading to cell expansion to occupy maximum space within the table.

The equal-width appearance of the cells is due to the uniform percentage value assigned to each. If you were to increase the width of one cell slightly, you would observe it expanding while others shrink accordingly:

div {
  border: 1px solid #000;
  border-radius: 4px;
}

div ul {
  padding: 0;
  margin: 0;
}

div ul li {
  display: table-cell;
  width: 1%;
  text-align: center;
  border-right: 1px solid #000;
  padding: 10px 0;
}

div ul li:first-child {
  width: 3%;
}

div ul li:last-child {
  border-right: 0;
}
<div>
  <ul>
    <li><a href="#">Commits</a>
    </li>
    <li><a href="#">Branch</a>
    </li>
    <li><a href="#">Contribution</a>
    </li>
    <li><a href="#">anything</a>
    </li>
  </ul>
</div>

It's important to note that slight variations exist due to varying content lengths in the cells, which contribute to the calculation of their widths.

The choice of a small value like 1% allows additional cells to be added while still striving for an even distribution of available width. This way, cells are informed they do not have a minimum required width, promoting flexibility in adding new cells (though technically, 1% does indicate some width).

The absence of elements designated as display: table holds no consequence, as an anonymous table wrapper is automatically generated around the table-cells for proper rendering. This wrapper functions similarly to an unstyled element with display: table, where the table width is considered 'auto' for calculating percentage cell widths.

Answer №2

Have you heard of the 1% width table hack before?

This clever technique allows a table-cell to inherit its width from the parent div, enabling you to specify a proportional percentage of the cell's width.

If you're curious to see this hack in action, check out this CodePen demo where you can experiment and explore further:

http://codepen.io/ld0rman/pen/FCiLh


<ul>
  <li><a href="#">One</a></li>
  <li><a href="#">Two</a></li>
  <li><a href="#">Three</a></li>
  <li><a href="#">Four</a></li>
  <li><a href="#">Five</a></li>
</ul>  

CSS:


ul {
 list-style-type: none; 
 margin: 100px auto;
  width: 80%;
 }

 li {
   display: table-cell; 
   width: 1%;
    text-align: center;
    }

      a {
     display: block;
        border: 1px solid black;
      padding: 25px;
      text-decoration: none;
      color: white;
   text-transform: uppercase;
font-weight: bold;
background: grey;

 &:hover {
text-decoration: none; 
color: yellow;
background: darken(grey, 10%);
  }
   }

Just like in your github example, this code snippet demonstrates how the hack works. If you have any more questions, feel free to ask!

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

Retrieve the associative array from the user input by utilizing jQuery

How can I create an associative array from a form containing multiple text inputs using jQuery (or directly in JS)? Here's an example of the form: <form> <input type="text" name="name[13]" value="test 1" /> <input type="text" name="nam ...

What are the benefits of using PHP heredoc to create straightforward HTML code?

I've recently taken over the reins of a website and am looking to implement some changes. It's interesting because everything is structured using heredoc PHP scripts, yet there doesn't seem to be any actual PHP processing happening within th ...

Image floating next to a table

Trying to achieve something that I assumed would be straightforward, but CSS always has its surprises! The issue I'm facing is with an image floated to the left. Next to the image, I have a title, and below the title, but still alongside the image, I ...

Adding more pixels to the height of an element does not actually make it larger

Recently, I've been working with material UI and I have a scrolling list of items that I want to resize to be larger. However, I've noticed that no matter how I adjust the height in pixels, the items never exceed 140px. Below is the code snippet ...

Adaptable bootstrap grids and sections

<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fb9994948f888f899a8bbbced5c9d5c8">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet"/> <div class="c ...

Customizable external URLs in HTML files depending on the environment

Here are the SharePoint URLs for my production, QA, and development environments: Production: QA: Development: I need to adjust relative reference URLs in JS & CSS files (/sites/dev/) for each environment. Is there a way to make this configuration dyna ...

Dealing with CSS overflow issues in Safari, Chrome, and the ancient IE 6

Are Safari and Chrome compatible with overflow? How does IE 6 or higher handle overflow? ...

Tips for creating fully stretched columns within Bootstrap framework

I have a simple code example available on codepen, but here is the markup for convenience: <div class="container my-container"> <div class="row m-row justify-content-between"> <div class="col-2 my-col">One of three columns</div& ...

Conceal the pagination element within the Bootstrap aside on smaller screens

I am experiencing an issue with my web page layout. I have a DIV and an Aside element, inside the DIV there is a list with dynamic pagination. Everything seems to be functioning correctly, however on small devices, the Aside section is covering up the pa ...

Generate an adjustable grid layout (with rows and columns) to display information retrieved from an API request

I have recently started learning React JS and JavaScript. To practice, I am working on a small project where I am facing an issue with creating dynamic rows and columns. My aim is to display data in 4 columns initially and then move to a new row and column ...

The JS copy function is successful when operating on a single element, but it encounters issues when attempting to run on multiple elements, only copying

My code includes a copy function that copies the data from a textarea to the clipboard when a button is clicked. The functionality works perfectly for the first textarea, but for subsequent textareas, the buttons do not perform the copy action. Check out ...

Using HTML to automatically open a URL based on the input entered in a text box

I only have a basic understanding of HTML I am looking to add a feature on my website where users can input their order number into a text box, and it will automatically direct them to the corresponding order summary link. The links to these order summar ...

Modify the height of the panel-header in Bootstrap

I'm attempting to adjust the height of Bootstrap panel-header. However, when I modify the height using the following CSS code: style="height: 20px;" The title inside the header becomes misaligned. To see an example, check out this Plunker demo. Wh ...

Apply an opacity setting of 0.5 to the specific segment representing 30% of the scrollable div

I have a scrollable container for displaying messages. I would like to apply an opacity of 0.5 to the content in the top 30% of the container, as shown in this image: https://i.stack.imgur.com/NHlBN.png. However, when I tried using a background div with a ...

While attempting to make my div responsive, it unexpectedly became stuck to the navbar

After successfully creating a website that works fine on desktop, I encountered an issue when viewing it on my phone. The main content section, which features jokes, gets scrolled up along with the navbar. I followed a tutorial on YouTube to make the navba ...

Disappearing a menu list while zooming in on a page: The art of vanishing navigation

[QUESTION] Is there a way to make the Menu List disappear when zooming in on a webpage? For example: <-- Normal Page [No Zoom] --> [Logo] Profile Gallery Guestbook <-- Zoom In 120% --> [Logo] Profile Guestbook <-- Zoom In 150% --> ...

Styling the first visible item in ngRepeat using Angular

I am working with a list that is generated using ngRepeat, which looks like this <ul class="list-group"> <li class="list-group-item" ng-repeat="data in tree | filter:key"> {{data.name}} </li> </ul> My goal is to ma ...

Struggling to adjust the width of an <img> tag to fit the screen within a UITextView/HTML using NSAttributedString

When I try to load HTML with images into a UITextView, the images do not want to fit the width of the screen, they appear too large. Setting the width attribute for the IMG tag and using CSS does not seem to help. Here is the code snippet: var content = ...

Parent whose height is less than that of the child element

I'm working on creating a side menu similar to the one on this website. However, I'm facing an issue with the height of the #parent list element. I want it to match the exact same height as its content (the #child span - check out this jsfiddle). ...

The Vue application is unable to expand to 100% height when using a media query

Hello everyone, I'm currently using my Vue router for multiple pages, and I'm facing an issue where setting the height of the main container to 100% within this media query is not working as expected: @media screen and (min-width: 700px) { #sig ...