I like Excel for the ability to copy the whole column, and HTML tables don’t normally provide that. As a result, tons of time and nerves spent on copying cell by cell, cell by cell…
My friend and colleague (who btw likes HTML tables but in Adobe Dreamweaver graphic mode) needs a lot of data searched and sorted and put in table, but also copyable. Hm…
So, let’s make HTML tables great!
sidenote In my examples, tables are light blue, and cells are pink.
Option 1: Tables as columns
You can craft your own table out of a series of tables with float: left; style:

<style>
td {
border: 2px solid pink;
}
table {
border: 2px solid lightblue;
}
</style>
<table style="float: left">
<tr><th>Phrases</th></tr>
<tr><td>I am keen on kinship.</td></tr>
<tr><td>This toad is tedious.</td></tr>
<tr><td>Your blouse is a blasphemy.</td></tr>
</table>
<table style="float: left">
<tr><th>Translations</th></tr>
<tr><td>Мне нравится родство.</td></tr>
<tr><td>Эта жаба утомительна.</td></tr>
<tr><td>Твоя блузка это богохульство.</td></tr>
</table>
Reference
Option 2: Flex style div
You can make columns out of <div> elements, where the ‘table’ <div> will have style="display: flex;" and ‘column’ <div> will have style="flex: 1;". I added some glam for beauty.

<style>
.child {
flex: 1;
margin: 5px;
padding: 10px 20px;
}
</style>
<div style="display: flex;">
<div class="child" style="background: pink;">
pink<br>
red
</div>
<div class="child" style="background: lightblue;">
<div>blue</div>
<div>azure</div>
</div>
<div class="child" style="display: flex; background: lightgreen;">
<div class="child" style="background: green; color: white;">
green<br>
leafy</div>
<div class="child" style="background: teal; color: white;">
teal<br>
turquoise
</div>
</div>
</div>
I also added a green column to show that flex can make infinite amount of columns inside other columns. You can make rows with <br> or by wrapping each row in a column in another <div>.
Reference
- My dear friend who refuses to start her own blog (her: cheers, sweetie)
Small Django example
Default data
Say, you have a QuerySet (in views.py):
context['persons'] = Person.objects.all()
With fields name and nickname (in models.py):
class Person
name = models.Charfield(max_length=255)
nickname = models.Charfield(max_length=255)
Normally you would organize a table like this (in html template):
<table>
<tr>
<th>Name</th>
<th>Nickname</th>
</tr>
{% for person in persons %}
<tr>
<th>{{ person.name }}</th>
<th>{{ person.nickname }}</th>
</tr>
{% endfor %}
</table>
But you would get a normal table with uncopyable columns. To transform it, in views.py you need to transform the QuerySet.
Copyable
New view
In views, make new context values for every column:
persons = Person.objects.all()
names = [x.name for x in persons]
nicknames = [x.nickname for x in persons]
context['lists'] = [['Names', names], ['Nicknames', nicknames]]
There are copious amount of way to do that. To not go through the object for time multiplied by amount of fields, you can do something like that:
results = [['Name', []], ['Nicknames', []]]
for x in results:
results[0][1].append(x.name)
results[1][1].append(x.nickname)
Or since we have column names, use dictionary instead of list:
results = {'Name':[], 'Nicknames':[]}
for x in results:
results['Name'].append(x.name)
results['Nickname'].append(x.nickname)
Final HTML
And html will look like this (with Option 1: Tables as columns):
<style>
td {
border: 2px solid pink;
}
table {
border: 2px solid lightblue;
}
</style>
{% for header, list in lists %}
<table style="float: left">
<tr><th>{{ header }}</th></tr>
{% for elem in list %}
<tr><td>{{ elem }}</td></tr>
{% endfor %}
</table>
If you are using dictionary, change this line (add .items):
{% for header, list in lists.items %}