I would like to design something like shown below.How should I go about laying it out in html/css.Should I use table or flex would be better or something else?
-
Not an html expert but... my first try would probably be with a html 2d canvas and then javascript to render the grid of squares. The function could have a lookup table as input, which yields the seat status (blank, green, red) for each seat (row, column). – BitTickler Oct 13 '16 at 02:44
-
1What have you already tried to do ? – Jhecht Oct 13 '16 at 02:55
-
Either table or flex will work. And I don't think you should ask question like Should I do this ..., it's not what SO is for, not opinion base question. Try doing something and ask a specific question if you have problem. – Hp93 Oct 13 '16 at 03:28
-
@Hp93 The question asks what would be a better approach to the problem(Since table are easier to use in this case but not recommended).Also, my question contributes more to SO than your ridiculously overused good for nothing comment. – john doe Oct 13 '16 at 03:43
-
I think table would be the simplest. – A. L Oct 13 '16 at 04:02
-
@johndoe Chill dude, did I steal your meal? How about start with telling people what you have done? What do you know? Like why table is not a recommended solution? Why not start coding something other than showing a wireframe? – Hp93 Oct 13 '16 at 04:31
2 Answers
While questions of this style tend to produce opinion based answers and are as such frowned upon, I consider it legitimate to query expert opinions on how to tackle a certain problem before one starts to invest the work.
Now, by no means am I an html expert. But, while not mentioned in the question, I fancy this could be about displaying a status information in a web application rather than a static HTML document. Maybe within the context this is needed, there is a websocket or some timer based update of the page involved. And the seat allocation data might come from a server.
In the scenario I depicted above, one way to do it without a table could be as shown below. With a canvas (which allows for pretty rendering, if enough time is invested) and with a javascript function, using the data coming into the script from somewhere.
Whether this approach is preferable to a html table based solution, might come down to:
- How pretty is the picture supposed to be?
- What is less annoying work? Filling the html table with script or rendering the canvas picture in script?
Here a small prototype showing this approach:
<!DOCTYPE html>
<html>
<head>
<title>Demo of a canvas used to render seat plan in a Cinema</title>
<script>
var EMPTY = 0; // Still available for reservation and purchase.
var RESERVED = 1; // reserved but not yet paid for.
var BOUGHT = 2; // bought and paid for.
function Point(x,y) {
return { X: x, Y: y }
}
function Size(w,h) {
return {Width: w, Height: h}
}
function Rectangle(left,top,width,height) {
return {TopLeft: Point(left,top), Size: Size(width,height)}
}
function seatColorFromSeatStatus(seatStatus) {
switch(seatStatus) {
case EMPTY: return "white";
case RESERVED: return "green";
case BOUGHT: return "red";
default: return "black"; // Invalid value...
}
}
function mapSeatStatusToSeatColor(seats)
{
var result = {};
for(seat in seats) {
result[seat] = seatColorFromSeatStatus(seats[seat])
}
return result;
}
function seatKeyFromPosition(row,col) {
return JSON.stringify([row,col]);
}
function seatRowFromKey(key) {
return (JSON.parse(key))[0];
}
function seatColFromKey(key) {
return (JSON.parse(key)[1]);
}
function getSeatInfo(nrows,ncolumns) {
var result = { NRows: nrows, NColumns: ncolumns, Seats : {} };
for(row = 0; row < nrows; row++) {
for( col = 0; col < ncolumns; col++ ) {
result.Seats[seatKeyFromPosition(row,col)] = EMPTY;
}
}
result.Seats[seatKeyFromPosition(0,0)] = RESERVED;
result.Seats[seatKeyFromPosition(1,3)] = BOUGHT;
return result;
}
function renderSeat(ctx,r,fillColor) {
var backup = ctx.fillStyle;
ctx.strokeStyle = "blue";
ctx.rect(r.TopLeft.X+2,r.TopLeft.Y+2,r.Size.Width-4,r.Size.Height-4);
ctx.stroke();
ctx.fillStyle = fillColor;
ctx.fillRect(r.TopLeft.X+3,r.TopLeft.Y+3,r.Size.Width-5,r.Size.Height-5);
ctx.fillStyle = backup;
}
function renderSeatplan(seatInfo) {
var nrows = seatInfo.NRows;
var ncolumns = seatInfo.NColumns;
var seatColors = mapSeatStatusToSeatColor(seatInfo.Seats)
var canvas = document.getElementById("seatplan");
var ctx = canvas.getContext("2d");
var borderWidth = 10;
var rcContent = Rectangle(
borderWidth
, borderWidth
, canvas.width - 2 * borderWidth
, canvas.height - 2 * borderWidth
);
var szCell = Size(
Math.floor(rcContent.Size.Width / (ncolumns + 1))
, Math.floor(rcContent.Size.Height / (nrows + 1))
);
ctx.font = "30px Arial";
for(row = -1; row < nrows; row++) {
for(col = -1; col < ncolumns; col++ ) {
var r = Rectangle(
rcContent.TopLeft.X + szCell.Width * (col+1)
,rcContent.TopLeft.Y + szCell.Height * (row+1)
,szCell.Width
,szCell.Height
);
var center = Point(szCell.Width / 2, szCell.Height / 2);
if (row == -1 && col == -1) {
// nothing to render.
}
else if(row == -1){
// render column headers as numbers...
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.fillText(col.toString(),r.TopLeft.X+center.X,r.TopLeft.Y+center.Y+6);
}
else if(col == -1){
// render row header
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.fillText(String.fromCharCode(65 + row),r.TopLeft.X+center.X+4,r.TopLeft.Y+center.Y+6);
}
else
{
// render seat
renderSeat(ctx,r,seatColors[seatKeyFromPosition(row,col)]);
}
}
}
}
</script>
</head>
<body onload="renderSeatplan(getSeatInfo(10,16));">
<h1>Seatplan</h1>
<canvas id="seatplan" width="640" height="480"></canvas>
</body>
</html>
As this is a bare bone approach, it shall not be left unmentioned, that there are web frameworks (e.g. angular, node.js, ... ) which might solve the same problem in far fewer lines of code.
Last not least, my apologies to all those who actually are html experts and find my coding style terrible ;)

- 10,905
- 5
- 32
- 53
Use table, like this:
.table tbody tr td:not(:first-child) {
border: 1px solid blue;
width: 1em;
height:1em;
}
.table tbody tr td:first-child {
font-weight:bold;
}
.table tr td:nth-child(5) {
border:none!important;
}
.table {
border-spacing: 3em;
}
<table class="table">
<thead>
<tr>
<td></td>
<td>1</td>
<td>2</td>
<td>3</td>
<td></td>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td style="background-color:red;"></td>
<td></td>
<td></td>
<td></td>
<td style="background-color:red;"></td>
<td></td>
<td></td>
</tr>
<tr>
<td>B</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td style="background-color:red;"></td>
<td></td>
</tr>
<tr>
<td>C</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>D</td>
<td></td>
<td></td>
<td style="background-color:blue;"></td>
<td></td>
<td></td>
<td></td>
<td style="background-color:blue;"></td>
</tr>
</tbody>
</table>
You can also see the rendered table here

- 96
- 1
- 5