Create Meme Generator Using HTML, CSS, and JavaScript

Faraz

By Faraz -

Learn how to create a fun meme generator with HTML, CSS, and JavaScript. Follow this simple guide to build your own tool to create and share memes easily!


create-meme-generator-using-html-css-and-javascript.webp

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. JavaScript Code
  5. Conclusion
  6. Preview

Memes have become a huge part of internet culture, making us laugh and share relatable moments. Wouldn't it be fun to create your own custom memes? In this guide, we’ll walk you through building a simple meme generator using HTML, CSS, and JavaScript. This project is great for beginners who want to dive deeper into web development by combining design and interactivity. The meme generator allows users to upload an image, add custom text, and instantly generate a meme to download or share.

If you have basic knowledge of HTML, CSS, and JavaScript, this tutorial will be easy to follow. Even if you're new, don't worry! Each step is explained clearly, making it accessible for everyone. By the end of this guide, you'll have a fully functional meme generator that you can customize and expand with more features, like font styles and colors.

Building this meme generator will teach you how to handle image uploads, manipulate the HTML canvas, and add interactivity using JavaScript. These skills are essential for creating fun web applications and enhancing your understanding of front-end development.

Prerequisites:

Before we get started, here’s what you’ll need:

  1. Basic understanding of HTML, CSS, and JavaScript – Familiarity with creating web pages and writing simple scripts will be helpful.
  2. Code editor – Use any code editor like Visual Studio Code, Sublime Text, or Notepad++.
  3. Web browser – Any modern browser like Google Chrome or Firefox for testing your meme generator.

Source Code

Step 1 (HTML Code):

First, start by creating a simple HTML structure. This will include a file input for selecting images, text inputs for adding top, center, and bottom text, and a canvas where the meme will be displayed. Here’s a breakdown of each part of the code:

1. Document Type and Language

<!DOCTYPE html>
<html lang="en">
  • <!DOCTYPE html>: Declares the document type and version of HTML being used (HTML5).
  • <html lang="en">: Starts the HTML document and specifies that the language is English.

2. Head Section

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Meme Generator using JavaScript</title>
    <link rel="stylesheet" href="styles.css">
</head>
  • <meta charset="UTF-8">: Sets the character encoding for the document to UTF-8, allowing for a wide range of characters.
  • <meta name="viewport" content="width=device-width, initial-scale=1.0">: Makes the web page responsive, ensuring it scales correctly on different devices.
  • <title>Meme Generator using JavaScript</title>: Sets the title of the web page, which appears in the browser tab.
  • <link rel="stylesheet" href="styles.css">: Links to an external CSS file named styles.css for styling the page.

3. Body Section

<body>
<div class="container">
<h1>Meme Generator</h1>
.
.
.
</div>
</body>
  • <body>: The main content of the webpage starts here.
  • <div class="container">: A container for organizing the content of the meme generator.
  • <h1>Meme Generator</h1>: A header for the title of the application.

Meme Generator Controls

  • Image Upload:
    <input type="file" id="imageUpload" accept="image/*" class="upload-input">

    This input allows users to upload an image file for the meme.

  • Text Inputs:
    <input type="text" id="topText" placeholder="Top Text" class="text-input">
    <input type="text" id="centerText" placeholder="Center Text" class="text-input">
    <input type="text" id="bottomText" placeholder="Bottom Text" class="text-input">

    These inputs let users add text to the top, center, and bottom of the meme.

  • Font Color:
    <label class="color-label">Font Color:</label>
    <input type="color" id="fontColor" value="#FFFFFF" class="color-input">

    This input allows users to select a font color using a color picker.

  • Font Size:
    <label class="slider-label" for="fontSize">Font Size: <span id="fontSizeValue">50</span></label>
    <input type="range" id="fontSize" min="10" max="100" value="50" class="slider">

    A range slider that enables users to adjust the font size from 10 to 100.

  • Canvas:
    <canvas id="memeCanvas" class="canvas"></canvas>

    This is where the meme will be displayed and edited.

  • Download Button:
    <button id="downloadMeme" class="btn">Download Meme</button>

    A button for users to download the generated meme.

4. JavaScript Inclusion

<script src="script.js"></script>
  • This line includes an external JavaScript file named script.js, which will contain the functionality for the meme generator, such as handling image uploads, text input, and drawing on the canvas.

Step 2 (CSS Code):

Next, we will style the meme generator using CSS. Make the container look clean and user-friendly. Here’s a breakdown of the code:

Universal Selector

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
  • *: Targets all elements.
  • margin: 0;: Removes the default margin from all elements.
  • padding: 0;: Removes the default padding from all elements.
  • box-sizing: border-box;: Includes padding and border in the element's total width and height, making layout calculations easier.

Body Styling

body {
    font-family: 'Roboto', sans-serif;
    background-color: #f0f0f0; 
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px;
}
  • font-family: 'Roboto', sans-serif;: Sets the font for the body to Roboto.
  • background-color: #f0f0f0;: Gives the body a light gray background.
  • display: flex;: Enables flexbox layout.
  • justify-content: center;: Centers child elements horizontally.
  • align-items: center;: Centers child elements vertically.
  • padding: 20px;: Adds padding around the body.

Container Styling

.container {
    background-color: #ffffff; 
    border-radius: 20px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
    padding: 40px;
    width: 90%;
    max-width: 600px;
    text-align: center;
}
  • background-color: #ffffff;: Sets a white background for the container.
  • border-radius: 20px;: Rounds the corners of the container.
  • box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);: Adds a shadow effect below the container.
  • padding: 40px;: Adds space inside the container.
  • width: 90%;: Sets the width to 90% of its parent.
  • max-width: 600px;: Restricts the maximum width to 600px.
  • text-align: center;: Centers the text inside the container.

Heading Styling

h1 {
    font-size: 32px;
    margin-bottom: 20px;
    color: #333; /* Dark gray text */
}
  • font-size: 32px;: Sets the font size for the heading.
  • margin-bottom: 20px;: Adds space below the heading.
  • color: #333;: Sets the text color to dark gray.

Meme Generator Section

.meme-generator {
    display: flex;
    flex-direction: column;
    align-items: center;
}
  • display: flex;: Enables flexbox layout for the meme generator section.
  • flex-direction: column;: Arranges child elements in a column.
  • align-items: center;: Centers child elements horizontally.

Upload Input Styling

.upload-input {
    background-color: #f7f7f7; /* Light input background */
    color: #333; /* Dark text */
    padding: 12px;
    border: 2px solid #ddd; /* Light border */
    border-radius: 8px;
    margin: 10px 0;
    cursor: pointer;
    transition: border-color 0.3s;
}
.upload-input:hover {
    border-color: #007bff; /* Blue border on hover */
}
  • Styling for .upload-input: Provides a light gray background, dark text, padding, light border, rounded corners, and a pointer cursor.
  • :hover effect: Changes the border color to blue when the mouse hovers over it.

Text Input Styling

.text-input {
    display: block;
    width: 100%;
    margin: 10px 0;
    padding: 12px;
    font-size: 16px;
    border: 2px solid #ddd; /* Light border */
    border-radius: 8px;
    background-color: #f7f7f7; /* Light input background */
    color: #333; /* Dark text */
    transition: border-color 0.3s;
}
.text-input:focus {
    border-color: #007bff; /* Blue border on focus */
}
  • Styling for .text-input: Defines width, padding, border, and background similar to .upload-input, with a focus effect changing the border color to blue.

Slider Styling

.slider {
    -webkit-appearance: none;
    width: 100%;
    height: 8px;
    background: #ddd; /* Light gray slider */
    border-radius: 5px;
    outline: none;
    margin-bottom: 20px;
}
.slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 24px;
    height: 24px;
    background: #007bff; /* Blue thumb */
    border-radius: 50%;
    cursor: pointer;
}
.slider::-moz-range-thumb {
    width: 24px;
    height: 24px;
    background: #007bff; /* Blue thumb */
    border-radius: 50%;
    cursor: pointer;
}
  • Styling for .slider: Customizes the appearance of the slider, setting its dimensions and background color.
  • Slider thumb styles: Customizes the appearance of the slider thumb (the draggable part) for WebKit and Mozilla browsers.

Color Input Styling

.color-input {
    margin: 10px 0;
    padding: 12px;
    border: 2px solid #ddd; /* Light border */
    border-radius: 8px;
    width: 100%;
    background-color: #f7f7f7; /* Light input background */
    color: #333; /* Dark text */
}
  • Styling for .color-input: Similar to previous input fields with light background and dark text.

Canvas Styling

.canvas {
    display: block;
    width: 100%;
    height: auto;
    margin: 20px 0;
    border: 2px solid #ddd; /* Light border */
    border-radius: 12px;
}
  • Styling for .canvas: Displays the canvas as a block element with a border and rounded corners.

Button Styling

.btn {
    background-color: #007bff; /* Blue button */
    color: #fff; /* White text */
    padding: 12px 20px;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    cursor: pointer;
    transition: background-color 0.3s;
    margin-top: 10px;
}
.btn:hover {
    background-color: #0056b3; /* Darker blue on hover */
}
  • Styling for .btn: Defines a blue button with white text, padding, and rounded corners. The button darkens when hovered over.
* {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}

body {
	font-family: 'Roboto', sans-serif;
	background-color: #f0f0f0; 
	display: flex;
	justify-content: center;
	align-items: center;
	padding: 20px;
}

.container {
	background-color: #ffffff; 
	border-radius: 20px;
	box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
	padding: 40px;
	width: 90%;
	max-width: 600px;
	text-align: center;
}

h1 {
	font-size: 32px;
	margin-bottom: 20px;
	color: #333; /* Dark gray text */
}

.meme-generator {
	display: flex;
	flex-direction: column;
	align-items: center;
}

.upload-input {
	background-color: #f7f7f7; /* Light input background */
	color: #333; /* Dark text */
	padding: 12px;
	border: 2px solid #ddd; /* Light border */
	border-radius: 8px;
	margin: 10px 0;
	cursor: pointer;
	transition: border-color 0.3s;
}

.upload-input:hover {
	border-color: #007bff; /* Blue border on hover */
}

.text-input {
	display: block;
	width: 100%;
	margin: 10px 0;
	padding: 12px;
	font-size: 16px;
	border: 2px solid #ddd; /* Light border */
	border-radius: 8px;
	background-color: #f7f7f7; /* Light input background */
	color: #333; /* Dark text */
	transition: border-color 0.3s;
}

.text-input:focus {
	border-color: #007bff; /* Blue border on focus */
}

.slider-label {
	margin: 10px 0;
	color: #333; /* Dark gray text */
	font-size: 16px;
}

.slider {
	-webkit-appearance: none;
	width: 100%;
	height: 8px;
	background: #ddd; /* Light gray slider */
	border-radius: 5px;
	outline: none;
	margin-bottom: 20px;
}

.slider::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	width: 24px;
	height: 24px;
	background: #007bff; /* Blue thumb */
	border-radius: 50%;
	cursor: pointer;
}

.slider::-moz-range-thumb {
	width: 24px;
	height: 24px;
	background: #007bff; /* Blue thumb */
	border-radius: 50%;
	cursor: pointer;
}

.color-label {
	margin: 10px 0;
	color: #333; /* Dark gray text */
	font-size: 16px;
}

.color-input {
	margin: 10px 0;
	padding: 12px;
	border: 2px solid #ddd; /* Light border */
	border-radius: 8px;
	width: 100%;
	background-color: #f7f7f7; /* Light input background */
	color: #333; /* Dark text */
}

.canvas {
	display: block;
	width: 100%;
	height: auto;
	margin: 20px 0;
	border: 2px solid #ddd; /* Light border */
	border-radius: 12px;
}

.btn {
	background-color: #007bff; /* Blue button */
	color: #fff; /* White text */
	padding: 12px 20px;
	border: none;
	border-radius: 8px;
	font-size: 16px;
	cursor: pointer;
	transition: background-color 0.3s;
	margin-top: 10px;
}

.btn:hover {
	background-color: #0056b3; /* Darker blue on hover */
} 

Step 3 (JavaScript Code):

The core of the meme generator is the JavaScript functionality that allows users to upload an image, add text, and generate the meme on the canvas. Let's break down the JavaScript code step by step:

Key Elements and Functions

  1. Element Selection:
    const imageUpload = document.getElementById('imageUpload');
    const memeCanvas = document.getElementById('memeCanvas');
    const topTextInput = document.getElementById('topText');
    const centerTextInput = document.getElementById('centerText');
    const bottomTextInput = document.getElementById('bottomText');
    const downloadMemeBtn = document.getElementById('downloadMeme');
    const fontSizeInput = document.getElementById('fontSize');
    const fontSizeValue = document.getElementById('fontSizeValue');
    const fontColorInput = document.getElementById('fontColor');
    const ctx = memeCanvas.getContext('2d');
    let uploadedImage;
    • This section selects various HTML elements (like inputs and the canvas) and stores them in constants for easy access.
    • ctx gets the drawing context of the canvas, which is used to draw images and text.
  2. Image Upload Handling:
    imageUpload.addEventListener('change', (event) => {
        const reader = new FileReader();
        reader.onload = function () {
            const img = new Image();
            img.onload = function () {
                memeCanvas.width = img.width;
                memeCanvas.height = img.height + 100; 
                ctx.drawImage(img, 0, 0);
                uploadedImage = img;
                drawText(); 
            };
            img.src = reader.result;
        };
        reader.readAsDataURL(event.target.files[0]);
    });
    • An event listener is added to the image upload input. When a user uploads an image, a FileReader reads it.
    • Once the file is read, a new image object is created and drawn onto the canvas. The canvas dimensions are set based on the uploaded image dimensions plus some extra height for text.
    • After the image is drawn, drawText() is called to add any existing text.
  3. Text Input Handlers:
    topTextInput.addEventListener('input', drawText);
    centerTextInput.addEventListener('input', drawText);
    bottomTextInput.addEventListener('input', drawText);
    fontSizeInput.addEventListener('input', updateFontSize);
    fontColorInput.addEventListener('input', drawText); 
    • Event listeners are added to the text input fields and the font size and color inputs.
    • When the user types in the text fields or changes the font size or color, the drawText() or updateFontSize() functions are called to reflect these changes on the canvas.
  4. Font Size Update Function:
    function updateFontSize() {
        const fontSize = fontSizeInput.value;
        fontSizeValue.textContent = fontSize; 
        drawText(); 
    }
    • This function updates the displayed font size value and calls drawText() to redraw the text with the new font size.
  5. Drawing Text on the Canvas:
    function drawText() {
        if (!uploadedImage) return; 
        ctx.clearRect(0, 0, memeCanvas.width, memeCanvas.height);
        ctx.drawImage(uploadedImage, 0, 0);
    
        const fontSize = fontSizeInput.value;
        ctx.fillStyle = fontColorInput.value; 
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 4;
        ctx.font = `${fontSize}px Impact`;
        ctx.textAlign = 'center';
    
        ctx.fillText(topTextInput.value.toUpperCase(), memeCanvas.width / 2, fontSize);
        ctx.strokeText(topTextInput.value.toUpperCase(), memeCanvas.width / 2, fontSize);
        ctx.fillText(centerTextInput.value.toUpperCase(), memeCanvas.width / 2, memeCanvas.height / 2);
        ctx.strokeText(centerTextInput.value.toUpperCase(), memeCanvas.width / 2, memeCanvas.height / 2);
        ctx.fillText(bottomTextInput.value.toUpperCase(), memeCanvas.width / 2, memeCanvas.height - 20);
        ctx.strokeText(bottomTextInput.value.toUpperCase(), memeCanvas.width / 2, memeCanvas.height - 20);
    }
    • This function first checks if an image is uploaded. If not, it exits early.
    • It clears the previous canvas drawing and redraws the uploaded image.
    • The text is drawn on the canvas using specified styles (font size, color, stroke, etc.). The text is centered based on the canvas width and height.
  6. Downloading the Meme:
    downloadMemeBtn.addEventListener('click', () => {
        const link = document.createElement('a');
        link.href = memeCanvas.toDataURL();
        link.download = 'meme.png';
        link.click();
    });
    • When the user clicks the download button, a temporary anchor element is created.
    • The canvas content is converted to a data URL, and this URL is set as the href of the anchor.
    • The download attribute is set to specify the filename for the downloaded image. Finally, the anchor is programmatically clicked to initiate the download.
const imageUpload = document.getElementById('imageUpload');
const memeCanvas = document.getElementById('memeCanvas');
const topTextInput = document.getElementById('topText');
const centerTextInput = document.getElementById('centerText');
const bottomTextInput = document.getElementById('bottomText');
const downloadMemeBtn = document.getElementById('downloadMeme');
const fontSizeInput = document.getElementById('fontSize');
const fontSizeValue = document.getElementById('fontSizeValue');
const fontColorInput = document.getElementById('fontColor');
const ctx = memeCanvas.getContext('2d');
let uploadedImage;

imageUpload.addEventListener('change', (event) => {
    const reader = new FileReader();
    reader.onload = function () {
        const img = new Image();
        img.onload = function () {
            memeCanvas.width = img.width;
            memeCanvas.height = img.height + 100; 
            ctx.drawImage(img, 0, 0);
            uploadedImage = img;
            drawText(); 
        };
        img.src = reader.result;
    };
    reader.readAsDataURL(event.target.files[0]);
});

topTextInput.addEventListener('input', drawText);
centerTextInput.addEventListener('input', drawText);
bottomTextInput.addEventListener('input', drawText);
fontSizeInput.addEventListener('input', updateFontSize);
fontColorInput.addEventListener('input', drawText); 

function updateFontSize() {
    const fontSize = fontSizeInput.value;
    fontSizeValue.textContent = fontSize; 
    drawText(); 
}

function drawText() {
    if (!uploadedImage) return; 
    ctx.clearRect(0, 0, memeCanvas.width, memeCanvas.height);
    ctx.drawImage(uploadedImage, 0, 0);

    const fontSize = fontSizeInput.value;
    ctx.fillStyle = fontColorInput.value; 
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 4;
    ctx.font = `${fontSize}px Impact`;
    ctx.textAlign = 'center';

    ctx.fillText(topTextInput.value.toUpperCase(), memeCanvas.width / 2, fontSize);
    ctx.strokeText(topTextInput.value.toUpperCase(), memeCanvas.width / 2, fontSize);

    ctx.fillText(centerTextInput.value.toUpperCase(), memeCanvas.width / 2, memeCanvas.height / 2);
    ctx.strokeText(centerTextInput.value.toUpperCase(), memeCanvas.width / 2, memeCanvas.height / 2);

    ctx.fillText(bottomTextInput.value.toUpperCase(), memeCanvas.width / 2, memeCanvas.height - 20);
    ctx.strokeText(bottomTextInput.value.toUpperCase(), memeCanvas.width / 2, memeCanvas.height - 20);
}

downloadMemeBtn.addEventListener('click', () => {
    const link = document.createElement('a');
    link.href = memeCanvas.toDataURL();
    link.download = 'meme.png';
    link.click();
});

Final Output:

create-meme-generator-using-html-css-and-javascript.gif

Conclusion:

Now you’ve created a fun and easy meme generator using HTML, CSS, and JavaScript. This project not only allows you to create and share memes, but it also introduces you to key web development concepts like working with images, canvas manipulation, and event handling in JavaScript.

By completing this project, you’ve gained hands-on experience with some important web technologies. You learned how to structure a simple HTML page, style it with CSS for a clean and user-friendly interface, and use JavaScript to add interactivity, such as uploading images, adding text, and generating memes. The skills you’ve developed in this project will be valuable in building more complex and dynamic web applications.

Feel free to customize and expand your meme generator.

That’s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Post

Please allow ads on our site🥺