Create a Facebook Post Box Clone in HTML CSS & JavaScript
Last Updated :
23 Jul, 2024
We will see how can we implement a Facebook post box clone with the help of HTML, CSS, and JavaScript.
A Facebook post is a message or update shared by a user on their profile or page. It typically includes text, photos, videos, or links. Users can tag locations, and friends, express feelings, and set privacy settings. Other users can react, comment, and share the post. It serves as a way to share updates, connect with friends, and engage with a wider audience.
Prerequisites:
Preview:

CDN Links:
<script type="module" src="https://cdn.jsdelivr.net/npm/emoji-picker-element@^1/index.js"></script>
Approach
- Create the Facebook post box structure using HTML tags, like <main> and <section> tags for the create post containers, and <emoji-picker> to demonstrate how a typical emoji picker in a Facebook post will look like with corresponding classes and IDs attached to these elements.
- Add the different styling properties to the post using classes, pseudo-classes such as ::before and::after, and elements that will define the padding, margin, font sizes to text, alignments, colors, etc to the specific elements.
- In JavaScript, first, create a set of variables to store the textarea, post button, emoji picker, and the button to show or hide the emoji picker on click.
- Attach an eventListener() to the textarea which will detect on input whether the textarea is empty or not. If it is empty, the post button will be disabled by default. Otherwise, the post button will be enabled since the user is writing a post message.
- Similarly, attach another eventListener() to the emoji picker button which will toggle the visibility of the emoji picker on click.
- Attach an eventListener() on the emoji picker itself which will append the emoji selected to the textarea using the insertText() function, which is a part of the inserted text at the cursor module from the node package manager (npm).
- Attach an eventListener() on the post audience button which will change the audience to which this post should be visible to with appropriate radio buttons for selecting a particular choice.
Example: This example describes the basic implementation of a Facebook post box using HTML, CSS, and Javascript.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content=
"width=device-width, initial-scale=1.0">
<link rel="stylesheet" href=
"./style.css">
<script type="module" src=
"https://cdn.jsdelivr.net/npm/emoji-picker-element@^1/index.js">
</script>
<title>Facebook Post Box Clone</title>
</head>
<body>
<main class="post">
<div class="wrapper">
<section class="create-post">
<header class="header">
<h1>Create post</h1>
<div class="cross-icon">
<div class="cross-icon-mark"></div>
</div>
</header>
<div class="post-header">
<div class="profile-pic"></div>
<div class="user-info">
<div class="full-name">GeeksforGeeks</div>
<div class="post-audience">
<div class="friends-icon"></div>
<span class="audience-text">Friends</span>
<div class="drop-down"></div>
</div>
</div>
</div>
<div class="post-content">
<textarea name="post-desc" id="post-desc"
cols="30" rows="5"
placeholder="What's on you mind, Geek?"></textarea>
<div class="emoji-picker">
<emoji-picker class="light"></emoji-picker>
<i class="emoji" aria-label="Insert an emoji"
role="img"></i>
</div>
<div class="add-to-your-post">
<span class="add-to-post-text">Add to your post</span>
<div class="add-to-post-icons">
<div class="photo-video"></div>
<div class="tag-people"></div>
<div class="feeling-activity"></div>
<div class="check-in"></div>
<div class="gif"></div>
<div class="live-video"></div>
</div>
</div>
<button class="post-btn" disabled>Post</button>
</div>
</section>
<section class="post-audience-section">
<header class="post-audience-header">
<div class="arrow-left-icon"></div>
<h1>Post Audience</h1>
</header>
<div class="post-audience-content">
<h4>Who can see your post?</h4>
<p class="your-post-text">Your post will show up
in Feed, on your profile and in search results.</p>
<p> Your default audience is set to Only me,
but you can change the<br /> audience
of this specific
post.</p>
</div>
<div class="post-audience-options">
<div class="audience-option">
<div class="audience-option-left">
<div class="audience-option-icon earth"></div>
<div class="audience-option-details">
<div class="audience-option-text">Public</div>
<span class="audience-option-desc">Anyone on
or off Facebook</span>
</div>
</div>
<div class="audience-option-right">
<div class="radio-btn">
<input type="radio" name="audience-option-radio"
class="audience-option-radio">
</div>
</div>
</div>
<div class="audience-option">
<div class="audience-option-left">
<div class="audience-option-icon user-group"></div>
<div class="audience-option-details">
<div class="audience-option-text">Friends</div>
<span class="audience-option-desc">Your friends
on Facebook</span>
</div>
</div>
<div class="audience-option-right">
<div class="radio-btn">
<input type="radio" name="audience-option-radio"
class="audience-option-radio">
</div>
</div>
</div>
<div class="audience-option">
<div class="audience-option-left">
<div class="audience-option-icon user"></div>
<div class="audience-option-details">
<div class="audience-option-text">Friends except...</div>
<span class="audience-option-desc">Don't show
to some friends</span>
</div>
</div>
<div class="audience-option-right">
<div class="radio-btn">
<input type="radio" name="audience-option-radio"
class="audience-option-radio">
</div>
</div>
</div>
<div class="audience-option">
<div class="audience-option-left">
<div class="audience-option-icon specific-user"></div>
<div class="audience-option-details">
<div class="audience-option-text">
Specific friends</div>
<span class="audience-option-desc">Only
show to some friends</span>
</div>
</div>
<div class="audience-option-right">
<div class="radio-btn">
<input type="radio"
name="audience-option-radio"
class="audience-option-radio">
</div>
</div>
</div>
<div class="audience-option">
<div class="audience-option-left">
<div class="audience-option-icon lock"></div>
<div class="audience-option-details">
<div class="audience-option-text">Only me</div>
</div>
</div>
<div class="audience-option-right">
<div class="radio-btn">
<input type="radio"
name="audience-option-radio"
class="audience-option-radio">
</div>
</div>
</div>
<div class="audience-option">
<div class="audience-option-left">
<div class="audience-option-icon gear"></div>
<div class="audience-option-details">
<div class="audience-option-text">Custom</div>
<span class="audience-option-desc">Include
and exclude friends and lists</span>
</div>
</div>
<div class="audience-option-right">
<div class="radio-btn">
<input type="radio"
name="audience-option-radio"
class="audience-option-radio">
</div>
</div>
</div>
<div class="audience-option">
<div class="audience-option-left">
<div class="audience-option-icon star"></div>
<div class="audience-option-details">
<div class="audience-option-text">Close
friends</div>
<span class="audience-option-desc">Your
custom list</span>
</div>
</div>
<div class="audience-option-right">
<div class="radio-btn">
<input type="radio"
name="audience-option-radio"
class="audience-option-radio">
</div>
</div>
</div>
</div>
</section>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
CSS
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&amp;display=swap');
body {
font-family: 'Inter', sans-serif;
}
.post {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.wrapper {
height: 30rem;
transition: height 0.2s ease;
}
.wrapper.wrapper-active {
height: 20rem;
}
.create-post {
border-radius: 5px;
-webkit-box-shadow: 0 0 5px 1px grey;
box-shadow: 0 0 5px 1px grey;
}
.header {
position: relative;
display: flex;
justify-content: center;
align-items: center;
padding-right: 1.5rem;
}
.header::before,
h1,
.cross-icon {
content: '';
flex-basis: 100%;
}
.header::after {
content: &quot;&quot;;
position: absolute;
width: 100%;
height: 1px;
bottom: -0.25rem;
left: 0;
background-color: rgb(193, 190, 190);
}
h1 {
text-align: center;
}
.cross-icon {
text-align: right;
}
.cross-icon-mark {
cursor: pointer;
padding: 0.35rem;
border-radius: 50%;
background-image: url(https://static.xx.fbcdn.net/rsrc.php/v3/yY/r/fCbUcoRfiez.png);
background-position: 3.5px -483.5px;
background-size: 26px 1031px;
width: 15px;
height: 15px;
background-repeat: no-repeat;
display: inline-block;
}
.friends-icon {
background-image: url(https://static.xx.fbcdn.net/rsrc.php/v3/yZ/r/4qsdCsLNqKi.png);
width: 14px;
height: 14px;
background-position: center;
background-size: 100% auto;
background-repeat: no-repeat;
object-fit: cover;
object-position: 50% 50%;
}
.drop-down {
background-image: url(
https://static.xx.fbcdn.net/rsrc.php/v3/yY/r/fCbUcoRfiez.png);
background-position: 0px -980px;
background-size: 26px 994px;
width: 12px;
height: 12px;
background-repeat: no-repeat;
display: inline-block;
transform: scale(1.1);
}
.post-header {
padding: 1.5rem;
display: flex;
align-items: center;
gap: 1rem;
}
.profile-pic {
width: 3.5rem;
height: 3.5rem;
background-color: green;
background-position: center;
background-repeat: no-repeat;
background-size: auto 80%;
border-radius: 50%;
}
.full-name {
margin-bottom: 0.3rem;
}
.post-audience {
cursor: pointer;
background-color: #e4e6eb;
display: flex;
align-items: center;
gap: 0.25rem;
justify-content: space-around;
padding: 0.25rem;
border-radius: 5px;
}
.fa-sort-down {
margin-bottom: 0.5rem;
}
.post-audience:hover {
background-color: #d9dce3;
}
.post-content {
padding: 0 1.5rem 1.5rem 1.5rem;
}
textarea {
font-family: 'Inter', sans-serif;
font-size: 1.25rem;
width: 100%;
border: none;
resize: none;
outline: none;
line-height: 1.25;
}
.emoji-picker {
text-align: right;
margin-bottom: 1rem;
position: relative;
}
emoji-picker {
display: none;
position: absolute;
right: 0;
top: -26rem;
left: 65%;
}
.emoji {
border-radius: 50%;
cursor: pointer;
}
.add-to-your-post {
display: flex;
justify-content: space-between;
align-items: center;
gap: 7rem;
border: 1px solid rgb(193, 190, 190);
padding: 1.25rem 1rem;
border-radius: 5px;
}
.add-to-post-text {
font-weight: bold;
}
.add-to-post-icons {
display: flex;
gap: 1.25rem;
}
.add-to-post-icons div {
cursor: pointer;
width: 24px;
height: 24px;
background-position: center;
background-repeat: no-repeat;
background-size: auto 100%;
}
.photo-video {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yC/r/a6OjkIIE-R0.png);
}
.tag-people {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yC/r/MqTJr_DM3Jg.png);
}
.feeling-activity {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yk/r/yMDS19UDsWe.png);
}
.check-in {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yy/r/uywzfiZad5N.png);
}
.gif {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yX/r/j0Jp-GpONWx.png);
}
.live-video {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yF/r/v1iF2605Cb5.png);
}
.post-btn {
outline: none;
border: none;
width: 100%;
border-radius: 5px;
cursor: pointer;
padding: 0.75rem 0;
margin-top: 1rem;
font-family: 'Inter', sans-serif;
background-color: #1b74e4;
color: #ffffff;
font-size: 1rem;
}
.post-btn:hover {
background-color: rgba(27, 116, 228, 0.85);
}
.post-btn:disabled,
.post-btn[disabled] {
cursor: not-allowed;
background-color: #e4e6eb;
color: #bdc1c5;
}
.post-audience-section {
transform: translateY(-5rem);
display: none;
border-radius: 5px;
-webkit-box-shadow: 0 0 5px 1px grey;
box-shadow: 0 0 5px 1px grey;
}
.post-audience-header {
position: relative;
display: grid;
grid-template-columns: repeat(3, 1fr);
margin: 0 auto;
align-items: center;
padding-left: 1.5rem;
}
.post-audience-header::after {
content: &quot;&quot;;
position: absolute;
width: 100%;
height: 1px;
bottom: -0.25rem;
left: 0;
background-color: rgb(193, 190, 190);
}
.arrow-left-icon {
cursor: pointer;
font-size: 1.5rem;
color: #606770;
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yQ/r/1gFkxZXWOU8.png);
background-position: 0px -182px;
background-size: 26px 972px;
width: 20px;
height: 20px;
background-repeat: no-repeat;
display: inline-block;
}
.fa-arrow-left {
cursor: pointer;
background-color: #e4e6eb;
padding: 0.5rem 0.6rem;
border-radius: 50%;
}
.fa-arrow-left:hover {
background-color: #d9dce3;
}
.post-audience-content {
padding: 1rem 1rem 0 1rem;
}
.post-audience-content h4 {
margin: 0.25rem 0;
}
.your-post-text {
margin: 0.5rem 0 1rem 0;
}
.post-audience-options {
padding: 0 0.625rem 0.625rem 0.625rem;
overflow-y: scroll;
height: 15rem;
}
.audience-option {
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.625rem;
border-radius: 10px;
}
.audience-option:hover {
background-color: hsl(210, 12%, 97%);
}
.audience-option-left {
display: flex;
align-items: center;
gap: 1rem;
}
.audience-option-icon {
font-size: 1.75rem;
width: 36px;
height: 36px;
transform: scale(0.65);
}
.earth {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yT/r/0QOZ5Rw18zW.png);
}
.user-group {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/ym/r/GgYVAS1o2Dp.png);
}
.user {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yf/r/_OLjeOMXK05.png);
}
.specific-user {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yg/r/xZG_j_BgiWu.png);
}
.lock {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yw/r/fxRwLKfcAmo.png);
}
.gear {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yB/r/417zloHnnzB.png);
}
.star {
background-image:
url(https://static.xx.fbcdn.net/rsrc.php/v3/yX/r/QryT_9DQQgy.png);
}
.audience-option-icon i {
background-color: #e4e6eb;
border-radius: 50%;
}
.fa-earth-asia {
padding: 1rem;
}
.post-audience-section .fa-user-group {
padding: 1rem 0.75rem;
}
.fa-user {
padding: 1rem 1.1rem;
}
.fa-lock {
padding: 1rem 1.1rem;
}
.fa-gear {
padding: 1rem;
}
.fa-star {
padding: 1rem 0.9rem;
}
.audience-option-text {
font-weight: bold;
margin-bottom: 0.15rem;
}
.audience-option-radio {
transform: scale(1.5);
}
.audience-option.active {
background-color: hsl(210, 12%, 94%);
}
JavaScript
const textarea = document
.querySelector('#post-desc');
const postBtn = document
.querySelector('.post-btn');
const postAudienceBtn = document
.querySelector('.post-audience');
const backBtn = document.
querySelector('.arrow-left-icon');
const createPostSection = document.
querySelector('.create-post');
const postAudienceSection = document.
querySelector('.post-audience-section');
const emojiBtn = document.
querySelector('.emoji');
const emojiPicker = document.
querySelector('emoji-picker');
const audienceOptions = document.
querySelectorAll(".audience-option");
const radioBtns = document.
querySelectorAll(".audience-option-radio");
document.body.style.overflowX = 'none';
textarea.addEventListener("input", () => {
if (textarea.value != '')
postBtn.disabled = false;
else
postBtn.disabled = true;
})
emojiBtn.addEventListener("click", () => {
if (emojiPicker.style.display == 'none')
emojiPicker.style.display = 'block';
else
emojiPicker.style.display = 'none';
})
emojiPicker.addEventListener('emoji-click', e => {
textarea.value += e.detail.unicode;
})
postAudienceBtn.addEventListener('click', () => {
document.querySelector('.wrapper')
.classList.add('wrapper-active');
postAudienceSection.style.display = 'block';
createPostSection.style.display = 'none';
})
audienceOptions.forEach(option => {
option.addEventListener('click', e => {
if (!option.classList.contains('active')) {
option.classList.add('active');
e.currentTarget.children[1]
.children[0].children[0].checked = true;
}
for (let i = 0; i < audienceOptions.length; i++) {
if (e.currentTarget != audienceOptions[i]) {
audienceOptions[i].classList
.remove('active');
radioBtns[i].checked = false;
}
}
})
})
backBtn.addEventListener('click', () => {
document.querySelector('.wrapper')
.classList.remove('wrapper-active');
postAudienceSection.style.display = 'none';
createPostSection.style.display = 'block';
})
Output:
Similar Reads
Create a Guestbook using HTML CSS and JavaScript
This article will show how to create a GuestBook using HTML, CSS, and JavaScript that allows users to add their name, mobile number, room number, and address to the guestbook. We have written a code that generates a card with multiple input boxes and a submit button to store the guest's information
3 min read
Create a Contact Form using HTML CSS & JavaScript
A contact form is a web form used to collect user information and messages, facilitating communication between visitors and site owners. It is essential for feedback, inquiries, and support. Create a contact form using HTML for structure, CSS for styling, and JavaScript for validation and submission
3 min read
How to create Cookie Consent Box using HTML CSS and JavaScript ?
In this article, we will see how cookies are stored using the cookie consent box using HTML, CSS, & JavaScript.Cookies are small pieces of data that are stored on a user's device while browsing the website. Cookies are used to store information for faster access to data and provide a better user
4 min read
Create GeeksforGeeks Clone Using HTML CSS & JavaScript
In this article, we'll make a clone of the GeeksforGeeks website. The clone includes home, about, courses, and contact pages. On the home page, we've added sections like categories, features, testimonials, and FAQs, similar to the GFG website. We named our clone GeeksforGeeks 2.0 to avoid copyright
15+ min read
How to create Popup Box using HTML CSS and JavaScript?
Creating a popup box with HTML, CSS, and JavaScript improves user interaction on a website. A responsive popup appears when a button is clicked, featuring an HTML structure, CSS for styling, and JavaScript functions to manage visibility.ApproachCreate the Popup structure using HTML tags, Some tags a
3 min read
How to Create a Chips Component using HTML CSS & JavaScript ?
In this article, we will see how we can create a chip component with the help of HTML, CSS, and JavaScript. In a chip component, there are basically two sections: one is the content section, and the other is the cross-button section. Both should be under one container with a proper border-radius. Pr
3 min read
Create an OTP Verification Form in HTML CSS & JavaScript
When the application is loaded, there is a button through which the user can generate the OTP. Once the user generates the OTP, the form for verification becomes visible, the user needs to enter the correct OTP that is generated. When the user enters the OTP in the input field, and if the OTP matche
4 min read
How to create a Color Generator using HTML CSS and JavaScript ?
In this article, we will develop a Color Generator application using HTML, CSS, and JavaScript.In this application, we have created the Multi Format color generator. Users can select Colour Types like RGB, HEX, and CMYK. Use the sliders to customize the color and Inout field in case of HEX and color
6 min read
How to create a Popup Form using HTML CSS and JavaScript ?
To create a popup form using JavaScript, you can design a hidden overlay that becomes visible when triggered. We will use HTML for form elements, CSS for styling, and JavaScript to toggle the visibility of the overlay. This allows for a user-friendly and interactive way to display forms on your webp
3 min read
Create an QR Code Generator Project using HTML CSS & JavaScript
Today, more than 75% of websites and apps use QR codes to share links, contact info, or event details quickly. Here, youâll learn how to make your own QR Code Generator using HTML, CSS, and JavaScript. Weâll guide you step by step, so even if youâre a beginner, you can follow along easily. By the en
3 min read