Oops, I forgot my business card!
A while back, whilst trying to think of possible internal projects that we could work on to level up the team's skills, we had the idea to create a digital business card. We live in a world where everything is going digital, everybody is more eco-conscious and mobile phones are our constant companions.
The idea is that you load the QR card page on your phone, then let a person scan the QR code which in turn adds your details to their contacts list on their phone.
Hopefully this article will give you an idea of the code needed to create a project like this and possibly inspire you to create your own.
HTML
The first step is to create a new directory called qrcard-demo.
Now let’s create a HTML page called index.html in the directory.
Note: Remember to change my profile image and information (see yellow highlights below) with yours!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>QR Card Demo</title>
</head>
<body>
<main>
<div class="card">
<!-- Card: Profile image -->
<figure class="card__figure">
<img class="card__image" src="avatar.jpg" alt="Grant Deelstra" />
</figure>
<!-- Card: Information -->
<div class="card__info">
<h1 class="card__name">Grant Deelstra</h1>
<p class="card__position">Frontend Developer</p>
</div>
<!-- Card: QR code message -->
<p class="card__message">
Scan the QR code to add my details to your phone
</p>
<!-- Card: QR code -->
<div id="qrcode" class="card__qrcode">
<img class="card__loading" src="loading.svg" />
</div>
</div>
</main>
</body>
</html>
CSS
Okay, let’s style it! We’ll create a new stylesheet called styles.css in our qrcard-demo directory.
*{
box-sizing: border-box;
}
html{
background-color: #ef4237;
}
main, .card{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem;
}
main{
min-height: 100vh;
}
.card{
--box-shadow: 0px 2px 5px 0px rgba(0,0,0,0.14), 0px 1px 10px 0px rgba(0,0,0,0.12), 0px 2px 4px -1px rgba(0,0,0,0.2);
max-width: 420px;
width: 100%;
background-color: #fff;
color: #333;
text-align: center;
border-radius: .5rem;
box-shadow: var(--box-shadow);
}
.card__figure{
width: 150px;
height: 150px;
border-radius: 50%;
overflow: hidden;
box-shadow: var(--box-shadow);
}
.card__image{
width: 100%;
height: auto;
}
.card__info{
border-bottom: 1px solid #ddd;
padding-bottom: .5rem;
margin-bottom: 1rem;
width: 100%;
}
.card__name{
margin: 0 0 1rem;
padding: 0;
}
.card__position{
margin-top: 0;
}
.card__message{
font-size: .75rem;
margin-bottom: 1rem;
}
.card__qrcode{
width: 275px;
height: 275px;
text-align: center;
}
.card__loading{
width: 64px;
height: auto;
}
Okay, cool! Lets link it in our index.html page between the <head> tags:
...
<link rel="stylesheet" href="styles.css">
</head>
JavaScript
Now the nitty, gritty stuff! Let’s create a file called qrcard.js in our qrcard-demo directory.
Let’s add it to our page along with the QR Code Styling script just above the closing </body> tag:
...
<script type="text/javascript" src="https://unpkg.com/qr-code-styling@1.5.0/lib/qr-code-styling.js"></script>
<script type="module" src="qrcard.js"></script>
</body>
vCard
We’re going to create the vCard string that’ll have the contact details you want to share. The string will be specially formatted so it can be read and added to a phone’s contact list.
We will be using a library called vcard-creator and for this purpose, loading it as an ESM module. It can be also used with node or your favourite bundler.
Note: Remember to change the vCard information with yours!
// Import the 'vcard-creator' module
import VCard from 'https://cdn.skypack.dev/vcard-creator';
// Create a vCard instance
const myVCard = new VCard();
// Add details to the vCard instance
myVCard
.addName("Deelstra", "Grant")
.addCompany("Hatchd")
.addJobtitle("Frontend Developer")
.addEmail("grant@hatchd.com.au")
.addPhoneNumber("123456789", "WORK")
.addAddress("", "Level 3", "108 St Georges Terrace", "Perth", "", "6000", "Australia")
.addURL("https://www.hatchd.com.au");
// Get the vCard string
const vCardString = myVCard.toString();
Good! We have created the vCard instance along with the vCard string, so now let’s go and create the QR code.
vCard Image
Heads up. To show an image in the vCard, you can use an URL, however most mobile devices require a base64 encoded string. In combination with QR code limitations, this base64 string needs to be tiny, as it will be the majority of the data within the QR code.
For this project, I’ve found using a GIF image with a file size under 850 bytes to work best and encode it as a base64 string.
// Adding a base64 GIF image string to the vCard
myVCard.addPhoto(logoBase64, 'GIF');
To view what additional data you can include in the vCard, I suggest looking at the vcard-creator website.
QR Code
The QR codes are a great, accessible way of sharing our contact details from our devices.
However, QR codes do have their limitations on the amount of data you can store in them e.g. you can store up to 4,296 alphanumeric characters of arbitrary text. For more information, check out qrcode.com.
To create our QR code, we will be using the QR Code Styling library. They also have a GUI generator located at https://qr-code-styling.com. You can export the options from it to use with the library.
...
// Create the QR code instance
const qrCode = new QRCodeStyling({
width: 275,
height: 275,
margin: 0,
type: "svg",
data: vCardString, // The vCard string
image: "logo.svg",
dotsOptions: {
color: "#ef4237",
type: "classy-rounded"
},
backgroundOptions: {
color: "#fff"
},
imageOptions: {
crossOrigin: "anonymous",
margin: 5,
imageSize: 1
},
cornersSquareOptions: {
type: "dot"
},
qrOptions: {
typeNumber: 0,
mode: "Byte",
errorCorrectionLevel: "Q",
}
});
Note: If the QR code doesn’t look right, especially if smaller than anticipated. Try playing around with the qrOptions.errorCorrectionLevel.
The library has an included method to append the QR code to an element in the page:
qrCode.append(document.getElementById("qrcode"));
However, usually there’s a small gap of time during the creation of the QR code, especially if there’s a lot of data involved. In our example, we have a loading image (loading.svg) where the QR code is meant to be appended. The method below is another way you can append the QR code.
In this alternative approach, we get the QR code’s raw data, create an img element from it, remove the loading image then append the new QR code image.
...
// Append the QR code
qrCode.getRawData("canvas")
.then(blob => {
const qrDiv = document.getElementById("qrcode");
const imageUrl = URL.createObjectURL(blob);
const image = document.createElement("img");
image.src = imageUrl;
qrDiv.innerHTML = ""; // Remove the loading image
qrDiv.append(image);
})
Bonus tip! If you want to download the QR code as a SVG image, you can use this included method:
// Download the QR code as an image: qr-image.svg
qrCode.download({ name: "qr-image", extension: "svg" });
If you want to use this method, you will need to create a button in the index.html page with an id attribute of “download-qrcode” and wrap it in an addEventListener in our JavaScript such as:
...
const downloadButton = document.getElementById("download-qrcode");
downloadButton.addEventListener('click', (e) => {
e.preventDefault();
// Download the QR code as an image: qr-image.svg
qrCode.download({ name: "qr-image", extension: "svg" });
})
That’s pretty much it! You should now have a page with a card containing a QR code with your details, ready to be scanned and shared. And, you will never again have to panic if you forget your business card.