I have a python script which dynamically generates a HTML Table according to some specifications provided to it.
A sample generated output is given below,
As you can see, it is possible that,
- It is possible for two consecutive cells to be merged (it is done from the Python Script, again. With the help of Jinja2)
- It is also possible for one cell to be divided horizontally into two or more sections
^These two possibilities can occur at any position in the HTML table.
The main issue I am facing here is this that I am getting unnecessary spacing/padding in all my cells (which are not horizontally divided). I don’t understand the cause behind it and I can’t seem to resolve this issue either. Can anyone help me to identify what changes do I need to make to make it look more presentable (i.e., no unnecessary space above and below the text in all cells). For example, in the first cell, there’s unnecessary padding added above the “Calculus and Analytical Geometry” and also below the “Dr. Mushtaq Ahmed” Text. However, in the same HTML table, if you look at the cell which is horizontally divided into two sections, this padding is not being added.
Similarly, I want to somehow align the “Name” and the “Room” in one Row. For example, for the first Cell, “Dr. Mushtaq Ahmed” and “Room #1” should be aligned in same row (rather than in two different rows). I have tried to make different changes to achieve this but they don’t seem to work properly (One change did work for me, but it disrupted the shape of the Horizontally divided cell and hence, I didn’t adopt it)
What I am actually looking to get is similar to this image,
The code for the HTML Table I shared above is as follows,
:root { --border-strong: 3px solid #777; --border-normal: 1px solid gray; } body { font-family: Georgia, 'Times New Roman', Times, serif; } table>caption { font-size: 6mm; font-weight: bolder; letter-spacing: 1mm; } /* 210 x 297 mm */ table { width: 297mm; height: 210mm; border-collapse: collapse; } td { border: var(--border-normal); position: relative; font-size: 2.6mm; font-weight: bold; } tbody tr:nth-child(odd) { background: #eee; } tbody tr:last-child { border-bottom: var(--border-strong); } tbody tr> :last-child { border-right: var(--border-strong); } /* top header */ .top_head>th { width: 54mm; height: 10mm; vertical-align: bottom; border-top: var(--border-strong); border-bottom: var(--border-strong); border-right: 1px solid gray; } .top_head :first-child { width: 27mm; border: var(--border-strong); } .top_head :last-child { border-right: var(--border-strong); } /* left header */ tbody th { border-left: var(--border-strong); border-right: var(--border-strong); border-bottom: 1px solid gray; } tbody>tr:last-child th { border-bottom: var(--border-strong); } /* row */ tbody td>div { height: 34mm; overflow: hidden; } .vertical_span_all { font-size: 5mm; font-weight: bolder; text-align: center; border-bottom: var(--border-strong); } .vertical_span_all div { height: 10mm; } /* td contents */ .note { font-size: 3mm; } .note :last-child { float: right; } @page { margin: 5mm; } .new-page { page-break-before: always; } .center { text-align: center; } .left { text-align: left; margin-left: 6px; /*margin-top: 10px;*/ } .right { text-align: right; margin-right: 4px; } .teacher { margin-left: 4px; } td{ height:175px; width:150px; }
<!DOCTYPE html> <html> <body> <!-- Heading --> <h1 class="center">CS-1D</h1> <!-- Table --> <table border="1"> <!-- Day/Periods --> <tr> <td class="center" ><br> <b>Day/Period</b></br> </td> <td class="center" > <b>I</b> </td> <td class="center" > <b>II</b> </td> <td class="center"> <b>III</b> </td> <td class="center"> <b>1:15-1:45</b> </td> <td class="center" > <b>IV</b> </td> <td class="center" > <b>V</b> </td> </tr> <!-- Monday --> <tr> <td class="center"> <b>Monday</b></td> <td colspan=1> <p class="left">Calculus and Analytical Geometry</p> <p class = "right">Room #1</p> <p class = "teacher">Dr.Mushtaq Ahmad</p> <!-- <p class="left">Calculus_and_Analytical_Geometry@Room_#1@Dr.Mushtaq_Ahmad</p> <p class="right">1</p> <p class="teacher"></p> --></td> <td colspan=1> </td> <td colspan=1> <p class="left">Programming Fundamentals</p> <p class = "right">Room #9</p> <p class = "teacher">Dr. Rabia Maqsood</p> <!-- <p class="left">Programming_Fundamentals@Room_#9@Dr._Rabia_Maqsood</p> <p class="right">1</p> <p class="teacher"></p> --></td> <td rowspan="6" class="center"> <h2>L<br>U<br>N<br>C<br>H</h2> </td> <td colspan=2> <p class="left">Programming Fundamentals - Lab</p> <p class = "right">Lab #1</p> <p class = "teacher">Muhammad Azeem Iftikhar</p> <!-- <p class="left">Programming_Fundamentals_-_Lab@Lab_#1@Muhammad_Azeem_Iftikhar</p> <p class="right">2</p> <p class="teacher"></p> --></td> </tr> <!-- Tuesday --> <tr> <td class="center"> <b>Tuesday</b> </td> <td colspan=1> </td> <td colspan=1> </td> <td colspan=1> <p class="left">English Composition and Comprehension - Lab</p> <p class = "right">Room #1</p> <p class = "teacher">Rida Akram<hr>English Composition and Comprehension</p> <!-- <p class="left">English_Composition_and_Comprehension_-_Lab@Room_#1@Rida_Akram<hr>English_Composition_and_Comprehension@Room_#7@Sadia_Ashfaq</p> <p class="right">1</p> <p class="teacher"></p> --><p class="left"></p> <p class = "right">Room #7</p> <p class = "teacher">Sadia Ashfaq</p> <!-- <p class="left">English_Composition_and_Comprehension_-_Lab@Room_#1@Rida_Akram<hr>English_Composition_and_Comprehension@Room_#7@Sadia_Ashfaq</p> <p class="right">1</p> <p class="teacher"></p> --></td> <td colspan=1> <p class="left">English Composition and Comprehension - Lab</p> <p class = "right">Room #1</p> <p class = "teacher">Rida Akram</p> <!-- <p class="left">English_Composition_and_Comprehension_-_Lab@Room_#1@Rida_Akram</p> <p class="right">1</p> <p class="teacher"></p> --></td> <td colspan=1> <p class="left">English Composition and Comprehension</p> <p class = "right">Room #3</p> <p class = "teacher">Farah Iqbal</p> <!-- <p class="left">English_Composition_and_Comprehension@Room_#3@Farah_Iqbal</p> <p class="right">1</p> <p class="teacher"></p> --></td> </tr> <!-- Wednesday --> <tr> <td class="center"> <b>Wednesday</b> </td> <td colspan=1> <p class="left">Islamic Studies/Ethics</p> <p class = "right">Room #7</p> <p class = "teacher">Zia Ahmad</p> <!-- <p class="left">Islamic_Studies/Ethics@Room_#7@Zia_Ahmad</p> <p class="right">1</p> <p class="teacher"></p> --></td> <td colspan=1> </td> <td colspan=1> <p class="left">English Composition and Comprehension</p> <p class = "right">Room #6</p> <p class = "teacher">Sadia Ashfaq</p> <!-- <p class="left">English_Composition_and_Comprehension@Room_#6@Sadia_Ashfaq</p> <p class="right">1</p> <p class="teacher"></p> --></td> <td colspan=1> </td> <td colspan=1> <p class="left">Applied Physics</p> <p class = "right">Room #1</p> <p class = "teacher">Waheed Ahmad</p> <!-- <p class="left">Applied_Physics@Room_#1@Waheed_Ahmad</p> <p class="right">1</p> <p class="teacher"></p> --></td> </tr> <!-- Thursday --> <tr> <td class="center"> <b>Thursday</b> </td> <td colspan=1> </td> <td colspan=1> <p class="left">Calculus and Analytical Geometry</p> <p class = "right">Room #5</p> <p class = "teacher">Dr.Mushtaq Ahmad</p> <!-- <p class="left">Calculus_and_Analytical_Geometry@Room_#5@Dr.Mushtaq_Ahmad</p> <p class="right">1</p> <p class="teacher"></p> --></td> <td colspan=1> <p class="left">Programming Fundamentals</p> <p class = "right">Room #10</p> <p class = "teacher">Dr. Rabia Maqsood</p> <!-- <p class="left">Programming_Fundamentals@Room_#10@Dr._Rabia_Maqsood</p> <p class="right">1</p> <p class="teacher"></p> --></td> <td colspan=1> <p class="left">English Composition and Comprehension</p> <p class = "right">Room #4</p> <p class = "teacher">Farah Iqbal</p> <!-- <p class="left">English_Composition_and_Comprehension@Room_#4@Farah_Iqbal</p> <p class="right">1</p> <p class="teacher"></p> --></td> <td colspan=1> <p class="left">Applied Physics</p> <p class = "right">Room #1</p> <p class = "teacher">Waheed Ahmad</p> <!-- <p class="left">Applied_Physics@Room_#1@Waheed_Ahmad</p> <p class="right">1</p> <p class="teacher"></p> --></td> </tr> <!-- Friday --> <tr> <td class="center"> <b>Friday</b> </td> <td colspan=1> <p class="left">Islamic Studies/Ethics</p> <p class = "right">Room #6</p> <p class = "teacher">Zia Ahmad</p> <!-- <p class="left">Islamic_Studies/Ethics@Room_#6@Zia_Ahmad</p> <p class="right">1</p> <p class="teacher"></p> --></td> <td colspan=2> <p class="left">Introduction to Information and Communication Technology - Lab</p> <p class = "right">Lab #4</p> <p class = "teacher">Aqsa Younas</p> <!-- <p class="left">Introduction_to_Information_and_Communication_Technology_-_Lab@Lab_#4@Aqsa_Younas</p> <p class="right">2</p> <p class="teacher"></p> --></td> <td colspan=2> <p class="left">English Composition and Comprehension - Lab</p> <p class = "right">Room #3</p> <p class = "teacher">Amna Farooq</p> <!-- <p class="left">English_Composition_and_Comprehension_-_Lab@Room_#3@Amna_Farooq</p> <p class="right">2</p> <p class="teacher"></p> --></td> </tr> </table> </body> <p class = "new-page"></div> </html>
Here is the template.html
code which is being used to generate the HTML Files. Multiple HTML files are being generated (for different sections) and then they are combined to make a PDF file. Therefore, it is important that height of the table is maintained, so that every generated HTML file covers one complete page of PDF File. Although, I don’t need anybody to understand this template.html
file and any changes made in the above shared HTML code can easily be done in this file ultimately.
https://pastebin.com/154ErqUU
pasted the code on pastebin because character limit had exceeded.
Advertisement
Answer
Assign the following CSS rulesets:
Figure I
Selector | Property | Value |
---|---|---|
td |
position |
relative |
td |
padding |
0 |
td div |
position |
relative |
td p |
position |
absolute |
td p |
margin |
0 |
.course |
top |
0.5rem |
.course |
left |
0.5rem |
.room |
bottom |
0.5rem |
.room |
right |
0.5rem |
.teacher |
bottom |
0.5rem |
.teacher |
left |
0.5rem |
Basically <td>
has default padding and <p>
has default margins so they should zeroed out. All containers are position: relative
and all content is position: absolute
and should have a minimum of 2 directions from left
, top
, bottom
, and right
.
The double stacked cells that should be rowspan="1"
is too impractical since the rest of the cells would have to be rowspan="2"
on the Tuesday
row and then the other rows would be twice the size of a rowspan="1"
in order to be uniform. Instead there are two <div>
s stacked within that particular cell (Row 1, Column 3 of tbody
).
The entire table (with the exception of the borders) are set in rem
s and are referenced to the font-size
in html
(2.85mm = 1rem`). (See comments in example for details).
Figure II
Media | Long Side | Length | Width |
---|---|---|---|
HTML | width | 278.73mm | 214.89mm |
Paper | length | 279mm | 216mm |
You can adjust the whole table by changing the font-size
in html
, it appears 2.85mm is optimal. Also, the lunch column is reduced signifigantly which gave the rest of the table badly needed space.
There is JavaScript that adds the content, but I wrote it to avoid cluttering the HTML — it’s not a requirement for the solution.
Details are commented in example below
const data = [ { row: 0, column: 1, course: 'Calculus and Analytical Geometry', room: 'Room #1', teacher: 'Dr.Mushtaq Ahmad', split: null }, { row: 0, column: 3, course: 'Programming Fundamentals', room: 'Room #9', teacher: 'Dr. Rabia Maqsood', split: null }, { row: 0, column: 5, course: 'Programming Fundamentals - Lab', room: 'Lab #1', teacher: 'Muhammad Azeem Iftikhar', split: null }, { row: 1, column: 3, course: 'English Composition and Comprehension - Lab', room: 'Room #1', teacher: 'Rida Akram', split: 'A' }, { row: 1, column: 3, course: 'English Composition and Comprehension', room: 'Room #7', teacher: 'Sadia Ashfaq', split: 'B' }, { row: 1, column: 4, course: 'English Composition and Comprehension - Lab', room: 'Room #1', teacher: 'Rida Akram', split: null }, { row: 1, column: 5, course: 'English Composition and Comprehension', room: 'Room #3', teacher: 'Farah Iqbal', split: null }, { row: 2, column: 1, course: 'Islamic Studies/Ethics', room: 'Room #7', teacher: 'Zia Ahmad', split: null }, { row: 2, column: 3, course: 'English Composition and Comprehension', room: 'Room #6', teacher: 'Sadia Ashfaq', split: null }, { row: 2, column: 5, course: 'Applied Physics', room: 'Room #1', teacher: 'Waheed Ahmad', split: null }, { row: 3, column: 2, course: 'Calculus and Analytical Geometry', room: 'Room #5', teacher: 'Dr.Mushtaq Ahmad', split: null }, { row: 3, column: 3, course: 'Programming Fundamentals', room: 'Room #10', teacher: 'Dr. Rabia Maqsood', split: null }, { row: 3, column: 4, course: 'English Composition and Comprehension', room: 'Room #4', teacher: 'Farah Iqbal', split: null }, { row: 3, column: 5, course: 'Applied Physics', room: 'Room #1', teacher: 'Waheed Ahmad', split: null }, { row: 4, column: 1, course: 'Islamic Studies/Ethics', room: 'Room #6', teacher: 'Zia Ahmad', split: null }, { row: 4, column: 2, course: 'Introduction to Information and Communication Technology - Lab', room: 'Lab #4', teacher: 'Aqsa Younas', split: null }, { row: 4, column: 3, course: 'English Composition and Comprehension - Lab', room: 'Room #3', teacher: 'Amna Farooq', split: null }, ]; const t = document.querySelector('table').tBodies[0]; const tRows = [...t.rows]; const cellData = (obj) => { let r = obj.row; let c = obj.column; let cell = tRows[r].cells[c]; if ('split' in obj) { let A, B; switch (obj.split) { case 'A': A = cell.querySelector('.A'); A.children[0].textContent = obj.course; A.children[1].textContent = obj.room; A.children[2].textContent = obj.teacher; break; case 'B': B = cell.querySelector('.B'); B.children[0].textContent = obj.course; B.children[1].textContent = obj.room; B.children[2].textContent = obj.teacher; break; default: cell.children[0].textContent = obj.course; cell.children[1].textContent = obj.room; cell.children[2].textContent = obj.teacher; break; } } }; data.forEach((obj) => cellData(obj));
/* ✳️ Rulesets pertaining to question */ :root { --thin: 1px solid #777; --thick: 3px solid #777; --split: 0.5px solid #777; } /* Global Reference Length 2.85mm = 1rem Changing the font-size changes all lengths in rem units. */ html { font: 500 2.85mm/1.5 Georgia; } /* Letter Size Paper (8.5 x 11in) 216 x 279mm 75.78 x 97.89rem 816 x 1056px */ /* Actual Dimensions 1rem = 2.85mm ❉ width: 97.8rem / 278.73mm ✥ height: 75.4rem / 214.89mm */ table { width: 97.8rem; height: 75.4rem; border-collapse: collapse; table-layout: fixed; } caption { font-size: 2.4rem; /* ✥ 10.26mm / 3.6rem */ font-weight: bolder; letter-spacing: 0.4rem; } thead th { width: 16.8rem; /* ❉ x 5 */ height: 3.8rem; /* ✥ */ vertical-align: bottom; border-top: var(--thick); border-bottom: var(--thick); border-right: var(--thin); } thead th:first-child { width: 9.8rem; /* ❉ */ border: var(--thick); } thead th:last-child { border-right: var(--thick); } tbody th { position: relative; border-left: var(--thick); border-right: var(--thick); border-bottom: var(--thin); } tbody > tr:last-child th { border-bottom: var(--thick); } tbody tr:nth-child(odd) { background: #eee; } tbody tr:last-child { border-bottom: var(--thick); } tbody tr > th:last-child, tbody tr > td:last-child { border-right: var(--thick); } td { position: relative; /* ✳️ */ height: 13.6rem; /* ✥ x 5 */ padding: 0; /* ✳️ */ border: var(--thin); font-size: 1rem; font-weight: bold; } td div.A { position: relative; /* ✳️ */ height: 6.8rem; border-bottom: var(--split); } td div.B { position: relative; /* ✳️ */ height: 6.8rem; border-top: var(--split); } td p { position: absolute; /* ✳️ */ margin: 0; /* ✳️ */ } .course { top: 0.5rem; /* ✳️ */ left: 0.5rem; /* ✳️ */ } .room { bottom: 0.5rem; /* ✳️ */ right: 0.5rem; /* ✳️ */ } .teacher { bottom: 0.5rem; /* ✳️ */ left: 0.5rem; /* ✳️ */ } th.lunch { width: 4rem; /* ❉ */ } td.lunch { vertical-align: middle; text-align: center; } td.lunch b { font-size: 1.5rem; }
<!DOCTYPE html> <html lang="en"> <head> <title></title> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> <link href="https://website.com/path/to/style.css" rel="stylesheet" /> <style></style> </head> <body> <table> <caption> CS-1D </caption> <thead> <tr> <th>Day/Period</th> <th>I</th> <th>II</th> <th>III</th> <th class="lunch">1:15<br />-<br />1:45</th> <th>IV</th> <th>V</th> </tr> </thead> <tbody> <tr> <th>Monday</th> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td class="lunch" rowspan="5" colspan="1"> <b>L<br />U<br />N<br />C<br />H<br /></b> </td> <td colspan="2"> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> </tr> <tr> <th>Tuesday</th> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <div class="A"> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </div> <div class="B"> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </div> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> </tr> <tr> <th>Wednesday</th> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> </tr> <tr> <th>Thursday</th> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> </tr> <tr> <th>Friday</th> <td> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td colspan="2"> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> <td colspan="2"> <p class="course"></p> <p class="room"></p> <p class="teacher"></p> </td> </tr> </tbody> </table> <script src='https://website.com/path.to/script.js'></script> <script></script> </body> </html>