Make table cells square
Asked Answered
S

4

41

How to ensure that each cell of table should become square without using fixed sizes? And be responsive when they change width.

table {
  width: 90%;
}
td {
  width: 30%;
}
tr {
  /** what should go here? **/
}
<table>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
    <td>5</td>
    <td>6</td>
  </tr>
  <tr>
    <td>7</td>
    <td>8</td>
    <td>9</td>
  </tr>
<table>
Sisterhood answered 3/4, 2014 at 10:56 Comment(0)
O
65

New answer :

To make the table cells square, you can use the aspect-ratio property on a div inside the td element. Like this :

table {
  width: 90%;
}
td {
  width: 33.33%;
  position: relative;
}
td .content {
  aspect-ratio: 1 / 1 ;
  background: gold;
}
<table>
  <tr>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
  </tr>
  <tr>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
  </tr>
  <tr>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
  </tr>
</table>

Previous answer :

You can use the technique described in: Grid of responsive squares.

Adapted to your usecase with a table and square table cells, it would look like this:

table {
  width: 90%;
}
td {
  width: 33.33%;
  position: relative;
}
td:after {
  content: '';
  display: block;
  margin-top: 100%;
}
td .content {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: gold;
}
<table>
  <tr>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
  </tr>
  <tr>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
  </tr>
  <tr>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
    <td><div class="content">1</div></td>
  </tr>
</table>

FIDDLE demo

Ory answered 3/4, 2014 at 11:16 Comment(6)
Could both downvoters explain the reason pls I'm ok with that but it isn't very constructive without explanation.Ory
this solution doesn't work on android <4.3 stock browsers. Still cool though :)Geek
how to vertical-align:middle the content ?Affusion
@BradKent there is a technique described here : https://mcmap.net/q/37042/-grid-of-responsive-squares (see 3.Centering the content). You can also have a look at this #8865958Ory
Before align the text firstly you have to add " width: 100%; height: 100%;" to the "td .content {...}" and after you can align the text simpleLoyola
If absolutely positioning .content causes problems, then you can also use float.Endow
N
7

Here is my code: http://jsfiddle.net/vRLBY/1/

The key is to use:

td { width: 33%; padding-bottom: 33%; height: 0; }
td div { position: absolute }

because padding-bottom is defined in terms of the width. More information: http://absolide.tumblr.com/post/7317210512/full-css-fluid-squares

Note: Previously I posted a not working code (see here). Thanks to @web-tiki for reporting the bug ;-)

Norven answered 3/4, 2014 at 11:27 Comment(5)
well this has a pretty wierd effect in this fiddle : jsfiddle.net/webtiki/cM3ybOry
@web-tiki: For we it worked fine in fiddle. Can you describe the weired effect you are seeing?Norven
Never used jFiddle before, so I cannot say when it looks okay and when weird... ;-) I would suggest, that you have to delete the body { ... } from the CSS....Norven
well fiddle is very handy, you can edit it and save it to show us your technique working. It basicaly is like a webpage taht everyone can edit, save and share...Ory
@tampis I just checked with firefox and it is better but the tds aren't square. I'll make a screenshot to show you.Ory
P
1

If someone's looking for a solution that does not require fixed width property (even in percentage), here's what I came up with based on above answers and the link from approved answer:

td {
    height: 0;

    &:after, &:before {
        content: '';

        display: block;
        padding-bottom: calc(50% - 0.5em);
    }
}

It's kinda lame but it kills two birds with one stone:

  • does the trick
  • makes content aligned vertically
Posterior answered 17/6, 2019 at 22:35 Comment(1)
this is Sass/Less code rather than plain cssArmadillo
N
-1
td {
    display: inline-block; <--- this is the secret
    width:10px;
    height:10px;
    overflow: hidden;
}
Nonconformist answered 9/6, 2023 at 20:22 Comment(1)
Your answer contains code without explanation. It's better to include details about how your answer answers the question.Underwater

© 2022 - 2024 — McMap. All rights reserved.