Hey everyone. Welcome to today’s tutorial. In today’s tutorial, we will learn how to create a User Profile👨💼 UI Design. To create this UI Design we will use HTML, CSS, and JavaScript. We do not make use of external libraries and plugins to create this project.
As I have mentioned in my tutorials before, this kind of complicated design hardly finds application in real-world projects. However, they are a fun way to learn and explore new properties.
This is a simple project that gives you a small idea of how real-world social networking platforms work. It has a clean and responsive layout, using HTML, CSS, and JavaScript. This profile interface provides a profile picture, username, biography, number of followers or followings, and the number of posts made. This type of design is usually used to build social media apps. This project aims to give you an idea of how social media apps work. Keep in mind that building a social media app in reality is a very complex task. This is just an attempt to give you an idea.
Project Folder Structure:
Before we start coding let us take a look at the project folder structure. We create a project folder called – ‘Profile Design’. Inside this folder, we have three files. These files are – index.html,style.css and script.js. The first file is the HTML document while the second one is the stylesheet. last one file is javascript.
HTML:
We begin with the HTML code. First, copy the code below and paste it into your HTML document.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HTML User Profile👨💼 UI Design | Codehemu</title>
<link href="https://www.codehemu.com/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="profile-wrapper">
<div class="user-profile-section profile-box">
<div class="profile-image-container">
<img class="profile-banner">
<img class="user-avatar" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixvkbO0cWBf4i9L2zrXM2UPoW7ZTv_vmbgnXzATNBnDCer7paalfemzoWB5Qaa0zGhK-CksMHhsxMd3dFJI8WX-aQiDzt2eRRRMh2Chgc0cNQzRyAB_nDmHCAVhswGHUHl7f_ARNQcBaLQ-ALJE2Ybu0dtGJ7bDnUwr3WOvSxPU5D3CfNwXK-k17c/s1600/512x512.png" alt="codehemu">
</div>
<button class="action-button">Follow</button>
<div class="user-info">
<h1>Code Hemu</h1>
<p>codehemu.com/html</p>
</div>
<div class="about-profile">Web developer | CSS Animation | <a href="https://www.youtube.com/@codehemu" title="codehemu"><strong>@codehemu</strong></a> | A creative learning hub for aspiring browser extension creators.</div>
<ul class="stats-list">
<li><a><strong class="animated-count" data-target="3170">0</strong><span>Posts</span></a></li>
<li><a><strong class="animated-count" data-target="2598">0</strong><span>Followers</span></a></li>
<li><a><strong class="animated-count" data-target="149">0</strong><span>Following</span></a></li>
</ul>
</div>
<div class="user-posts-section profile-box">
<h2>Latest Posts</h2>
<div id="posts-container"></div>
</div>
</div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
HTML Overall Structure
The stylesheet is linked inside the <head>
. So you need to create a style.css file <link rel="stylesheet" type="text/css" href="style.css">
. There are two <img>
tags, one is for your profile cover photo and the other is for your profile picture. <div class="about-profile">...</div>
Below that is a place for your bio. The latest post <h2>
tag you see below will load the post used JavaScript inside the post container.
script.js is piled at the bottom. You need to create a script file.
CSS:
Next, we style the elements created by HTML to give them shape and add animation using CSS. Now copy the code provided to you below and paste it into your stylesheet.
body {
background: #f8f5f0;
font-family: sans-serif;
}
a {
text-decoration: none;
color: #7973ff;
}
/* --- Profile Container Styles --- */
.profile-wrapper {
margin: 1em auto;
width: 44.23em;
}
/* --- Box Styles (for the main profile box) --- */
.profile-box {
background: #fff;
border-radius: 0.3rem;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
border: .1em solid rgba(0, 0, 0, 0.2);
margin-bottom: 1em;
}
/* --- User Profile Image and Background --- */
.user-profile-section .profile-image-container {
margin: 0 auto;
text-align: center;
}
.user-profile-section .profile-image-container .profile-banner {
border-bottom: .2em solid #f5f5f5;
width: 44.23em;
height: 16em;
background: #7973ff;
background: linear-gradient(172deg, #7973ff, #ff7145);
}
.user-profile-section .profile-image-container .user-avatar {
margin: 0 auto;
background: #fff;
width: 7em;
height: 7em;
padding: 0.25em;
border-radius: .4em;
margin-top: -10em;
box-shadow: 0 0 .1em rgba(0, 0, 0, 0.35);
}
/* --- Action Button Styles --- */
.user-profile-section .action-button {
position: absolute;
font-size: 13px;
font-weight: bold;
cursor: pointer;
width: 7em;
background: #7973ff;
border: 1px solid #8566b1;
color: #fff;
outline: none;
border-radius: 0 .6em .6em 0;
padding: .80em;
transition: width 0.8s ease-in-out;
}
.user-profile-section .action-button:hover {
background: #b784ff;
transition: width 0.5s ease-in-out;
border: 1px solid #8566b1;
width: 10em;
}
/* --- User Info (Name, URL) & About Section --- */
.user-profile-section .user-info,
.user-profile-section .about-profile {
text-align: center;
padding: 0 1.5em;
}
.user-profile-section .user-info h1 {
font-family: sans-serif;
margin-top: 0.35em;
color: #292f33;
margin-bottom: 0;
}
.user-profile-section .user-info p {
font-family: sans-serif;
color: #8899a6;
font-size: 1.1em;
margin-top: 0;
margin-bottom: 0.5em;
}
.user-profile-section .about-profile {
color: #75787b;
font-size: 0.98em;
}
/* --- Statistics List Section --- */
.user-profile-section .stats-list {
font-family: sans-serif;
margin-bottom: 0;
cursor: pointer;
padding: 0;
list-style: none;
display: table;
width: 100.15%;
}
.user-profile-section .stats-list li {
margin: 0;
padding: 0;
width: 33.33334%;
display: table-cell;
text-align: center;
border-left: 0.1em solid transparent;
}
.user-profile-section .stats-list li:first-child {
border-left: 0;
}
.user-profile-section .stats-list li:first-child a {
border-bottom-left-radius: 0.3rem;
}
.user-profile-section .stats-list li:last-child a {
border-bottom-right-radius: 0.3rem;
}
.user-profile-section .stats-list li a,
.user-profile-section .stats-list li strong {
display: block;
}
.user-profile-section .stats-list li a {
background-color: #f7f7f7;
border-top: 1px solid rgba(242, 242, 242, 0.5);
border-bottom: .2em solid #f7f7f7;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(255, 255, 255, 0.4);
padding: .93em 0;
color: #46494c;
}
.user-profile-section .stats-list li a strong,
.user-profile-section .stats-list li a span {
font-weight: 600;
line-height: 1;
}
.user-profile-section .stats-list li a strong {
font-size: 2em;
}
.user-profile-section .stats-list li a span {
color: #717a7e;
}
.user-profile-section .stats-list li a:hover {
background: rgba(0, 0, 0, 0.05);
border-bottom: .2em solid #7973ff;
color: #7973ff;
}
.user-profile-section .stats-list li a:hover span {
color: #7973ff;
}
/* --- Posts Section Styles --- */
.user-posts-section {
margin-top: 1.5em;
padding: 1.5em;
text-align: center;
}
.user-posts-section h2 {
color: #292f33;
font-size: 1.8em;
margin-bottom: 1em;
border-bottom: 2px solid #e0e0e0;
padding-bottom: 0.5em;
display: inline-block;
}
.post-item {
background: #fff;
border-radius: 0.3rem;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
border: .1em solid rgba(0, 0, 0, 0.1);
margin-bottom: 1.5em;
padding: 1.5em;
text-align: left;
}
.post-item h3 {
color: #7973ff;
margin-top: 0;
margin-bottom: 0.5em;
font-size: 1.3em;
}
.post-item p {
color: #555;
line-height: 1.6;
margin-bottom: 1em;
}
.post-item .post-meta {
font-size: 0.85em;
color: #999;
text-align: right;
}
.post-item .post-image {
max-width: 100%;
height: auto;
border-radius: 0.2rem;
margin-bottom: 1em;
display: block;
}
JavaScript:
Next, we style the elements created by HTML to give them shape and add animation using javascript. Now copy the code provided to you below and paste it into your script.js file.
document.addEventListener('DOMContentLoaded', () => {
// --- Counter Animation Logic ---
const counters = document.querySelectorAll('.animated-count');
counters.forEach(counter => {
const target = +counter.getAttribute('data-target');
let current = 0;
const increment = target / 100;
const updateCounter = () => {
if (current < target) {
current += increment;
if (current > target) {
current = target;
}
counter.textContent = Math.ceil(current);
requestAnimationFrame(updateCounter);
} else {
counter.textContent = target;
}
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
updateCounter();
observer.unobserve(counter);
}
});
}, { threshold: 0.5 });
observer.observe(counter);
});
function get_image_url(size, text, options = {}) {
const {
fontFamily = "Arial",
fontSize = 40,
textColor = "#000000",
backgroundColor = "#E0E0E0",
imageFormat = "image/png",
jpegQuality = 0.9
} = options;
const [width, height] = size;
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// Set background color
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, width, height);
// Set text properties
ctx.font = `${fontSize}px ${fontFamily}`;
ctx.fillStyle = textColor;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
// Measure text to center it
const textMetrics = ctx.measureText(text);
const textWidth = textMetrics.width;
const textHeight = fontSize;
// Calculate position to center the text
const x = width / 2;
const y = height / 2;
ctx.fillText(text, x, y);
// Return the Data URL
if (imageFormat === "image/jpeg") {
return canvas.toDataURL(imageFormat, jpegQuality);
} else {
return canvas.toDataURL(imageFormat);
}
}
// --- Post Loading Logic ---
const postsContainer = document.getElementById('posts-container');
// Simulate fetching JSON data (replace with actual fetch from API if needed)
const postsData = [
{
"id": 1,
"title": "Creating Responsive Layouts with Flexbox",
"image": get_image_url([600,400], "Flexbox Layout"),
"content": "Learn how to master CSS Flexbox to build dynami...",
"date": "July 29, 2025",
"author": "Code Hemu"
},
{
"id": 2,
"title": "Introduction to JavaScript Promises",
"image": get_image_url([600,400], "JS Promises"),
"content": "Dive into the world of asynchronous JavaScript with Pro...",
"date": "July 28, 2025",
"author": "Code Hemu"
},
{
"id": 3,
"title": "A Beginner's Guide to Git and GitHub",
"image": get_image_url([600,400], "Git and GitHub"),
"content": "Get started with version control using Git and GitH...",
"date": "July 27, 2025",
"author": "Code Hemu"
},
{
"id": 4,
"title": "Mastering CSS Transitions and Animations",
"image": get_image_url([600,400], "CSS Animation"),
"content": "Elevate your web UI with smooth CSS transitions a...",
"date": "July 26, 2025",
"author": "Code Hemu"
}
];
// Function to create a post element from data
function createPostElement(post) {
const postDiv = document.createElement('div');
postDiv.classList.add('post-item');
// Add image if available
if (post.image) {
const postImage = document.createElement('img');
postImage.classList.add('post-image');
postImage.src = post.image;
postImage.alt = post.title + ' Image';
postDiv.appendChild(postImage);
}
const postTitle = document.createElement('h3');
postTitle.textContent = post.title;
postDiv.appendChild(postTitle);
const postContent = document.createElement('p');
postContent.textContent = post.content;
postDiv.appendChild(postContent);
const postMeta = document.createElement('div');
postMeta.classList.add('post-meta');
postMeta.textContent = `Posted on ${post.date} by ${post.author}`;
postDiv.appendChild(postMeta);
return postDiv;
}
// Loop through postsData and append each post to the container
postsData.forEach(post => {
const postElement = createPostElement(post);
postsContainer.appendChild(postElement);
});
});
JavaScript logic
The logic behind how the above script works is explained. Hopefully, here is a discussion about main logics that you need to know.
document.addEventListener('DOMContentLoaded', () => { ... });
: The script will run after the entire HTML document is loaded.counters.forEach(counter => { ... });
: This includes animation counter logic. Here, the data-target attribute number inside the counters element is collected and animates from zero to data-target number.get_image_url(size, text, options = {}){ ... };
: This function creates an image. For example, suppose you want to create an image with a height and width of 200 and the text Hello World inside. Then you would call this function like this- get_image_url([200,200], "Hello World")createPostElement(post) { ... };
: This function loads the post inside the HTML.
That’s it for this tutorial. If you have any queries, suggestions or feedback you can comment below. Happy Coding!
إرسال تعليق