I got this idea to whip up a realistic looking retro calculator just for the sheer fun of coding it out, and I figured "Why not document the whole journey in a blog for anyone to read and follow along?", so here we are !
To start with, you'll need some knowledge over the web dev trifecta: HTML, CSS and JS.
I picked the font Audiowide from Google Fonts because I felt it had a cool retro vibe to it.
Note: The layout and all the visual jazz of the calculator is going to be built in HTML and SCSS, and as for the calculator's logic, I'm using the power of Vanilla JS.
The Steps
I've broken this down into a series of steps which lets us create a calculator easily !!
Steps:
- Create a button
- Create a grid of buttons
- Create a retro display
- Create the case and put everything in it !!
- Add some JS magic
At the end of each section, you'll find a CodePen link that has the complete code. Feel free to check it out and tinker with it! 🛠️
So, let's get started !!
Creating a Retro Button
This is the basic layout I'm going to use for the button !!
We have a "button body" and the "button cap"
<main class="container">
<div class="button-body">
<button class="button-cap">1</button>
</div>
</main>
Styling our button body
Let's look at the layout of the button-body
display: flex;
justify-content: center;
width: 75px;
height: 75px;
padding-top: 2px;
I'm using flexbox here for layouts, and justify-content: center
sets the button-cap
to the center of the button-body
I picked the width
and height
by playing around with the values, I was satisfied with how 75px
looked and felt.
padding-top
lets me offset the button-cap
from the top of the button-body
Note: See how I'm not using align
properties that FlexBox provides for vertical alignment. If we were to use align-items: center
then the button-cap
would be aligned perfectly to the center of the button-body
, but that's not going to make the button look realistic...
Now, let's style the button !!
To give it a retro and realistic look, we need to employ the POWER OF THE SHADOWS and GRADIENTS !!!!
Shadows and gradients make flat things look like they have shadows and light shining on them, making them seem 3D even though they're not !!
For the shadows and gradients, I'm using this handly tool neumorphism.io
This lets me play around with shadow directions, shape and intensity !!
After playing around with the colours and values, I arrived at this !
background: linear-gradient(145deg, rgb(120, 118, 99), #fff9d6);
border-radius: 3px;
box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.1), 0 0px 2px rgba(16, 22, 26, 0.2),
0 0px 1px rgba(16, 22, 26, 0.2);
and now, we need to add some effects to the button, so when it's clicked, it feels looks like it was clicked !!
&:active {
transform: scale(0.95);
background: linear-gradient(145deg, rgb(120, 118, 99), #fff9d6);
box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.1), 0 0px 2px rgba(16, 22, 26, 0.2),
0 0px 1px rgba(16, 22, 26, 0.2);
}
&:
in SCSS is a nifty feature that allows me to style the active state of the button-body within the same class. When the button is in the "active" state (like when it's pressed), I've used it to make the button appear a bit smaller by scaling it down.
Styling our button cap
/* layout */
width: 65px;
height: 65px;
border-radius: 5px;
I've width
and height
to be slightly smaller than the button's body, and styled it as follows
border: none;
background: linear-gradient(145deg, #d6d2b4, #fff9d6);
box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.1), 0 0px 2px rgba(16, 22, 26, 0.2),
0 0px 1px rgba(16, 22, 26, 0.2);
as for effects, I'm just scaling it down and adding an on-hover property to change the cursor to a pointer.
&:active {
transform: scale(0.95);
background: linear-gradient(145deg, #d6d2b4, #fff9d6);
box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.1), 0 0px 2px rgba(16, 22, 26, 0.2),
0 0px 1px rgba(16, 22, 26, 0.2);
}
&:hover {
cursor: pointer;
}
and this should give us a button !!
Creating a grid of buttons
Now let's take this button and set them in a grid !!
Note: Using a framework like ReactJS is best for this, you can create one button component and use that instead of copy-pasting the code like I've done here lol
There's three main things to note here.
- Some buttons are blue
- The first 4 rows are laid out in a CSS Grids
- The last row is using FlexBox
To find the background-color: linear gradient
you want to use, play around with this neumorphism.io until you're satisfied.
I'm setting the first 4 rows with CSS Grid because it's the most convenient way to do so !
All you have to do is this !
.top-rows {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 3px;
}
If you open up your calculator app or if you have a calculator with you, then you'd notice that the buttons in the last row always stretch a little more than the buttons in other rows, and the most convenient way i could do this is using FlexBox, and playing with the width of the wide buttons
.bottom-row {
display: flex;
justify-content: space-between;
gap: 5px;
padding-top: 3px;
}
.wider-button {
width: 35%;
}
.wider-cap {
width: 90%;
}
here's the result !!
Create a retro display
Creating a display is pretty straight forward, I'm using an input with the following properties
<input class="display" readonly type="text" dir="rtl" maxlength="8" placeholder="88888" />
Styling the Input Box
For the layout, I've set the height
to 75px
to match the button body height, and a width
of 320px
to match the buttons when we put it in a calculator.
box-sizing: border-box;
overflow: hidden;
padding: 5px;
height: 75px;
width: 320px;
for the display colour, I picked this nice shade of green, and the box shadow makes the display look 3D and stuck in place, just like some old calculators I've seen.
background: rgba(56, 62, 37, 1);
box-shadow: inset 1px 1px 6px 0px #050505, 0px 0px 4px 2px #000,
0px 0px 4px 2px #777;
For the numbers, I picked the font
Autowide again.
color: black;
font-size: 3rem;
font-family: "Audiowide", cursive;
Here's the result !!
create a retro calculator case
for this all we have to do is wrap wrap the "Display" and "Buttons" in a "Calculator Case" Div and style it appropriately
<div class="calculator-case">
<input id="display" class="display" readonly type="text" dir="rtl" maxlength="8" placeholder="88888" />
<div class="button-grid">
.....
I picked a similar colour to buttons itself (i ran out of creativity here), but compensated for it with some box-shadows !!
.calculator-case {
/* layout */
display: flex;
flex-direction: column;
gap: 20px;
padding: 25px;
/* style */
border-radius: 15px;
background: #d6d2b4;
box-shadow: inset 5px 5px 18px #c7c3a7, inset -5px -5px 18px #e5e1c1;
}
Ths JS Magix
Alright, so the previous codepen had the JS in it. Most of it is your standard stuff, but I wanted this Calculator to behave retro too, so I added these in
Firstly, if the currentInput
is greater than 8
, i.e. if you're inputting a number bigger than 8 digits long, it just won't record the value.
function handleNumberClick(value) {
if (currentInput.length < 8) {
currentInput += value;
}
}
and secondly
function calculateResult() {
.....
currentInput = currentInput.length > 8 ? 'ERROR' : currentInput;
}
When I'm calculating the result, if the result is bigger longer than 8 digits, I just return an ERROR.
NOW, I KNOW THIS MAKES THE CALCULATOR PRETTY USELESS, BUT THIS IS A VANITY PROJECT SO YEAH, IT'S PRETTY USELESS.
Thank you for reading along.
PS: This is my first time writing something like this, and i pro-castinated the crap out of it. Initially i was going to write the blog in the css / html file itself, but i scraped that idea when my css file was filled with badly written comments (if u find them, sorry)
PPS: Lmk if you liked it, or if you have any feedback for me.
Top comments (0)