In the first part we talked about the
initiative A Year In Pixels and we exposed the benefits it has from our
point of view. Now, we want to talk about a possible implementation with HTML,
CSS and JS using localStorage.
NOTE: The first time you access to the demo you will have no data saved and the calendar will be empty but once you save a mood your browser will remember your choices no matter if you reload the page.
HTML
We used a <table> to simplify the reading of the data. If you think about it,
it is just tabulated data, so this structure is the one which best fits to our
purpouses. And we used PUGJS to
build our <table> easiest.
Each <td> has two custom attributes, [data-day] works as an id, so we could
store the information and then retrieve it easily, and [data-mood] is for
styling the cell according to the mood selected.
[data-day] is an unique id, built using the number of the day and the number
of the month, tied with a #, so the id for the first of January will be 1#1
and the id for the 28th of July will be 28#7.
The table has a <caption> that works as a title and it is a best practice
to avoid the user has to extract the meaning of what we are representing on the
table analyzing its content. And this is hepful no matter of the user, I mean
that is helpful if the user has visual or cognitive difficulties or not. The
cells that represent the legend of colors at the <tfoot> has a [title] just
to show the mood that each color represents.
CSS
Not many surprises.
- The gray color we use to represent the default mood (empty) has two different
opacities depending on where it is used. Since we are using Custom Properties,
instead of using two variables, we are just saving the channels information
and apply then within the
hsla()with the opacity that we need depending on the case. - The function
clamp()to make variable and fluid the font size of the heading (Please find more information about this and other CSS functions here). - We use attibutes selectors to apply the color to the cells.
:root {
--default-color: 0, 0%, 87%;
}
caption {
padding: 0.5rem 0.5rem 1.5rem;
font-size: clamp(1.5rem, 50ch, 5vw);
font-weight: 700;
}
[data-mood="happy"] {
background-color: var(--happy-color);
}
JavaScript
It is easy. When the page loads the script tries to retrieve data from the
localStorage. If there is data, it will fill the cells with the moods
selected, if not, a calendar will be created and save.
LocalStorage
localStorage is an
simple API
to work with. It could be volatile because the data saved could be deleted if
the users clears the information saved at his browser. But it is perfect for the
demo because of its low complexity and which user clears oftenly the data
saved by the browser but those whom works on web development?. Futhermore,
since the information is stored in your personal browser becomes more personal
if possible.
Cells
Each cell is reponsible to handle its state. Each one has an handler with a
counter within used to move throught the different moods. The cell will create
or update its mood depending on the coincidence or not of data with its unique
id, and finally each cell with modify and save the object on the localStorage.
Tech debts
There are at least a couple of things that I could improve on the demo, I write them down if you feel collaborative and want to participate with me or fork the demo:
- Make the day column (with the numbers) and the row of the months fixed for mobile devices, so users could handle the table easily if they not loose the reference and context of the current column and row if they scroll the page (horizontally or vertically).
- Update the value of each cell from the current mood. If you reload the page, when you click on a cell with a mood previously settled, the inner counter starts from 0, not from the current mood. And that is a little bit annoying.