32

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>
web-tiki
  • 87,261
  • 27
  • 200
  • 230
Ganesh Bhosle
  • 1,283
  • 6
  • 14
  • 33

3 Answers3

58

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

Community
  • 1
  • 1
web-tiki
  • 87,261
  • 27
  • 200
  • 230
  • 1
    Could both downvoters explain the reason pls I'm ok with that but it isn't very constructive without explanation. – web-tiki Apr 03 '14 at 12:04
  • this solution doesn't work on android <4.3 stock browsers. Still cool though :) – Marcel Falliere Aug 06 '15 at 09:21
  • 4
    how to vertical-align:middle the content ? – Brad Kent Feb 25 '16 at 14:36
  • @BradKent there is a technique described here : http://stackoverflow.com/a/20457076/1811992 (see 3.Centering the content). You can also have a look at this http://stackoverflow.com/questions/8865458/how-to-align-text-vertically-center-in-div-with-css – web-tiki Feb 25 '16 at 14:46
  • Before align the text firstly you have to add " width: 100%; height: 100%;" to the "td .content {...}" and after you can align the text simple – Egor Jul 05 '17 at 07:36
  • If absolutely positioning `.content ` causes problems, then you can also use `float`. – thdoan Aug 03 '20 at 20:24
5

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 ;-)

Stephan Kulla
  • 3,996
  • 2
  • 19
  • 32
  • well this has a pretty wierd effect in this fiddle : http://jsfiddle.net/webtiki/cM3yb/ – web-tiki Apr 03 '14 at 11:37
  • @web-tiki: For we it worked fine in fiddle. Can you describe the weired effect you are seeing? – Stephan Kulla Apr 03 '14 at 11:41
  • 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.... – Stephan Kulla Apr 03 '14 at 11:48
  • 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... – web-tiki Apr 03 '14 at 11:50
  • 1
    @tampis I just checked with firefox and it is better but the `td`s aren't square. I'll make a screenshot to show you. – web-tiki Apr 03 '14 at 11:58
0

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
SOReader
  • 4,837
  • 3
  • 25
  • 50