Real-World Web Projects 🚀
Welcome to my active workspace! This isn't just a static gallery—it's a collection of real-world, fully functional web applications designed to solve actual problems. Every project here is practical, interactive, and ready to use. Explore the clean source code and test the live working models right in your browser.
Featured Projects
🕒 Interactive Digital Clock
A seamless time-tracking interface built with native web technologies and responsive styling.
📋 Semantic HTML Page
A Common Page Needed and Everytime Asked : What is Semantic HTML .
📋 To-do List with saving As Excel
An interactive and responsive To-Do List application powered by Vue.js for seamless state management and dynamic UI updates. It allows users to add, delete, and toggle the status of daily tasks. Additionally, it integrates FileSaver.js, enabling users to export and download their tracked tasks directly into an Excel (.csv) file for easy record-keeping.
Project 1: Interactive Digital Clock
Explanation: A real-time digital clock built using HTML, CSS, and JavaScript. It uses the setInterval() function to fetch and update the system time every second without reloading the page.
Code View:
<div class="clock-container">
<span id="digital-clock">00:00:00</span>
</div>
.clock-container {
background: #222;
color: #5bb3b3;
padding: 20px;
border-radius: 8px;
text-align: center;
font-family: 'Courier New', monospace;
font-size: 2rem;
font-weight: bold;
box-shadow: 0 4px 10px rgba(0,0,0,0.2);
width: max-content;
margin: 0 auto;
}
function updateClock() {
const now = new Date();
const timeString = now.toLocaleTimeString();
document.getElementById('digital-clock').textContent = timeString;
}
// Update time every 1000 milliseconds (1 second)
setInterval(updateClock, 1000);
updateClock(); // Run immediately on load
Live Result:
Project 2: Semantic HTML Page
Explanation: A real-time digital clock built using HTML, CSS, and JavaScript. It uses the setInterval() function to fetch and update the system time every second without reloading the page.
Code View:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Semantic HTML Example</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header>
<h1>Welcome to My Website</h1>
<nav>
<ul>
<li><a href="#home">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#services">Services</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>
<main>
<aside>
<h3>Related Links</h3>
<ul>
<li><a href="#">Privacy Policy</a></li>
<li><a href="#">Terms of Service</a></li>
</ul>
</aside>
<article>
<section id="home">
<h2>Home Section</h2>
<p>This is the home section of the page, introducing visitors to the website.</p>
</section>
<section id="about">
<h2>About Us</h2>
<p>We are a company that values quality and customer satisfaction.</p>
</section>
<section id="services">
<h2>Our Services</h2>
<ul>
<li>Web Development</li>
<li>Mobile App Development</li>
<li>UI/UX Design</li>
</ul>
</section>
<section id="contact">
<h2>Contact Us</h2>
<form>
<label for="name">Name:</label>
<input type="text" id="name" name="name">
<label for="email">Email:</label>
<input type="email" id="email" name="email">
<label for="message">Message:</label>
<textarea id="message" name="message"></textarea>
<button type="submit">Send</button>
</form>
</section>
</article>
</main>
<footer>
<p>© 2026 My Website</p>
</footer>
</body>
</html>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 20px;
}
header {
background: #333;
color: #fff;
padding: 10px;
text-align: center;
}
nav ul {
list-style-type: none;
padding: 0;
}
nav ul li {
display: inline;
margin: 0 10px;
}
nav ul li a {
color: white;
text-decoration: none;
}
main {
display: flex;
justify-content: space-between;
margin-top: 20px;
}
article {
flex: 3;
}
aside {
flex: 1;
background: #f4f4f4;
padding: 5px;
margin-right: 20px;
}
footer {
background: #333;
color: white;
text-align: center;
padding: 10px;
margin-top: 20px;
}
h1, h2, h3 {
margin-bottom: 10px;
}
p, ul, form {
margin-bottom: 20px;
}
label, input, textarea {
display: block;
width: 100%;
margin-bottom: 10px;
}
button {
display: block;
background: #333;
color: white;
padding: 10px;
border: none;
cursor: pointer;
}
button:hover {
background: #555;
}
// Run immediately on load
Live Result:
Project 3: To-do List with saving As Excel
Explanation: A real-time digital clock built using HTML, CSS, and JavaScript. It uses the setInterval() function to fetch and update the system time every second without reloading the page.
Code View:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Todo List</title>
<link rel="stylesheet" href="styles.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<nav>
<h1>
To-Do List Web App
</h1>
</nav>
<main id="todolist">
<div class="container">
<div class="left-column">
<form name="newform" @submit.prevent="addItem">
<input type="text" name="newitem" id="newitem" v-model="newitem.label" placeholder="Title" required>
<textarea type="text" name="newitem" id="detail" v-model="newitem.description" placeholder="Description"></textarea>
<button type="submit">Save</button>
</form>
</div>
<div class="right-column">
<div class="section-header">
<h4>Title</h4>
<h4>Description</h4>
<h4>Status</h4>
</div>
<template v-if="todo.length">
<transition-group name="todolist" tag="ul">
<li v-for="item in todoByStatus" :class="item.done ? 'done' : ''" :key="item.id">
<span class="label">{{ item.label }}</span>
<p class="description">{{ item.description }}</p>
<div class="actions">
<button class="btn-picto" type="button" @click="markAsDoneOrUndone(item)" :aria-label="item.done ? 'Undone' : 'Done'" :title="item.done ? 'Undone' : 'Done'">
<i aria-hidden="true" class="material-icons">{{ item.done ? 'check_box' : 'check_box_outline_blank' }}</i>
</button>
<button class="btn-picto" type="button" @click="deleteItemFromList(item)" aria-label="Delete" title="Delete">
<i aria-hidden="true" class="material-icons">delete</i>
</button>
</div>
</li>
</transition-group>
<togglebutton
label="Move done items at the end?"
name="todosort"
v-on:clicked="clickontoogle" />
</template>
<p v-else class="emptylist">Your todo list is empty.</p>
</div>
</div>
<!--This is the extra option that i have added-->
<!--you can also save your task into excel-->
<div class="bottom-table">
<table>
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Status</th>
</tr>
</thead>
<tbody id="doneTasksTableBody"></tbody>
</table>
</div>
<button id="save-button">Save to Excel</button>
</main>
<!--use vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<script src="app.js"></script>
</body>
</html>
* {
margin:0;
padding:0;
}
html, body {
font-size: 1.1rem;
font-family: 'Quicksand', sans-serif;
height: 100%;
padding-bottom: 20%;
background-image: url("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRg3Dz6KSQ2SYwQm_qrJJbxSSUFxf_0m8uflIxY9M0MIfFfwnKkfW9XLqXkgaFORI2P_oQ&usqp=CAU");
color: #FFF;
background-repeat: no-repeat;
background-size: cover; /* Use 'cover' to scale and fit the image */
background-attachment: fixed; /* Keep the background fixed */
}
.container {
display: flex;
justify-content: space-between;
width: 100%;
padding: 10px;
padding-top:40px;
}
.left-column {
width: 40%;
position:relative;
background-color: #f7f7f7; /* Set a background color for the left column */
padding: 20px; /* Add padding for spacing */
border-radius: 10px; /* Add border radius for rounded corners */
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); /* Add a subtle shadow */
}
nav{
margin-left:0;
}
nav h1 {
background:#fff;
color:#000;
font-weight:normal;
font-size:18px;
letter-spacing:0.05em;
padding:10px;
}
/* Style the form elements within the left column */
.left-column form {
display: flex;
flex-direction: column;
}
.left-column label {
font-weight: bold;
margin-bottom: 10px;
}
.left-column input[type="text"] {
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
.left-column textarea {
padding: 10px;
padding-top:10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
resize: vertical; /* Allow vertical resizing of the textarea */
min-height: 300px; /* Set a minimum height for the textarea */
}
.left-column button[type="submit"] {
background-color: #51bd55;
color: #fff;
padding: 10px 20px;
font-size:18px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
.left-column button[type="submit"]:active{
color:#000;
}
.left-column button[type="submit"]:active:after{
background:transparent;
}
.left-column button[type="submit"]:hover:before{
opacity:1;
}
/* ... (previous CSS styles) left style... */
.right-column {
width: 58%;
padding: 20px;
border-radius: 10px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}
.section-header {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 2px solid #007BFF;
}
.section-header h4 {
font-weight: bold;
}
.label {
font-weight: bold;
}
.description {
color: #555;
margin-top: 5px;
}
.actions {
margin-top: 10px;
}
.btn-picto {
background: none;
border: none;
cursor: pointer;
color: #007BFF;
margin-right: 10px;
font-size: 20px;
}
.btn-picto:hover {
color: #0056b3;
}
.done {
text-decoration: line-through;
color: #555;
}
#todolist {
padding:1rem 2rem 2rem;
max-width:100%;
height:100%;
}
#todolist .emptylist {
margin-top:2.6rem;
text-align:center;
letter-spacing:.05em;
font-style:italic;
opacity:0.8;
}
#todolist ul {
margin-top:3.8rem;
list-style:none;
}
#todolist .todolist-move {
transition: transform 1s;
}
#todolist li {
display:flex;
margin:0 -0.4rem 10px;
padding:1.1rem 4rem;
justify-content:space-between;
align-items:center;
background:#fff;
color:#000;
}
#todolist .actions {
flex-shrink:0;
padding-left:0.7em;
}
#todolist .label {
position:relative;
transition:opacity .2s linear;
}
#todolist .done .label {
opacity:.6;
}
#todolist .done .label:before {
content:'';
position:absolute;
top:50%;
left:-.5rem;
display:block;
width:0%;
height:1px;
background:#000;
animation:strikeitem .3s ease-out 0s forwards;
}
#todolist .btn-picto {
border:none;
background:none;
-webkit-appearance:none;
cursor:pointer;
color:#000;
}
/* TOOGLE COMPONENT */
.togglebutton-wrapper {
margin-top:1em;
}
.togglebutton-wrapper label {
display:flex;
justify-content:flex-end;
align-items:center;
}
.togglebutton-wrapper input {
position:absolute;
left:-9999px;
}
.togglebutton-wrapper .togglebutton-label {
font-size:.8rem;
letter-spacing:.1em
}
.togglebutton-wrapper .tooglebutton-box {
position:relative;
display:block;
margin-left:0.6em;
width:38px;
height:22px;
background:white;
/*border:1px solid black;*/
border-radius:999px;
cursor:pointer;
}
.togglebutton-wrapper .tooglebutton-box:before {
content:'';
position:absolute;
top:2px; left:2px;
display:block;
width:18px; height:18px;
/*border:1px solid #FF6666;*/
border-radius:50%;
background:#000;
opacity:0.7;
transition: all .2s ease-in-out;
}
.togglebutton-wrapper.togglebutton-focus .tooglebutton-box {
box-shadow:0px 0px 0px 3px rgba(0,0,0,0.1);
}
.togglebutton-wrapper.togglebutton-checked .tooglebutton-box:before {
left:calc(100% - 4px - 16px);
opacity:1;
}
.description {
font-size: 1rem;
margin-top: 0.2rem;
opacity: 0.8;
font-style: italic;
}
/* ... (previous CSS styles) ... */
.bottom-table {
margin-top: 20px;
margin-bottom: 20px;
overflow-x: auto; /* Add horizontal scroll for small screens */
}
table {
width: 100%;
border-collapse: collapse;
border: 2px solid #62c465;
}
table th,
table td {
padding: 10px;
text-align: left;
}
table th {
background-color: #62c465;
color: #fff;
}
table tr:nth-child(even) {
background-color: #8aa88b;
}
table tr:hover {
background-color: #754605;
}
#save-button{
background-color: #51bd55;
color: #fff;
padding: 10px 20px;
font-size:18px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
Vue.component('togglebutton', {
props: ['label', 'name'],
template: `<div class="togglebutton-wrapper" v-bind:class="isactive ? 'togglebutton-checked' : ''">
<label v-bind:for="name">
<span class="togglebutton-label">{{ label }}</span>
<span class="tooglebutton-box"></span>
</label>
<input v-bind:id="name" type="checkbox" v-bind:name="name" v-model="isactive" v-on:change="onToogle">
</div>`,
model: {
prop: 'checked',
event: 'change'
},
data: function() {
return {
isactive:false
}
},
methods: {
onToogle: function() {
this.$emit('clicked', this.isactive)
}
}
});
var todolist = new Vue({
el: '#todolist',
data: {
newitem: {
label: '',
description: ''
},
sortByStatus: false,
todo: [
{ id: 1, label: "Task 1", description: "Description for Task 1", done: false },
{ id: 2, label: "Task 2", description: "Description for Task 2", done: false },
{ id: 3, label: "Task 3", description: "Description for Task 3", done: false }
]
},
methods: {
addItem: function () {
if (this.newitem.label.trim() !== '') {
this.todo.push({ id: Math.floor(Math.random() * 9999) + 10, label: this.newitem.label, description: this.newitem.description, done: false });
this.newitem.label = '';
this.newitem.description = '';
}
},
markAsDoneOrUndone: function (item) {
item.done = !item.done;
if (item.done) {
moveTaskToDoneTable(item);
}
},
deleteItemFromList: function (item) {
let index = this.todo.indexOf(item);
if (index !== -1) {
this.todo.splice(index, 1);
}
},
clickontoogle: function (active) {
this.sortByStatus = active;
}
},
computed: {
todoByStatus: function () {
if (!this.sortByStatus) {
return this.todo;
}
var sortedArray = []
var doneArray = this.todo.filter(function (item) { return item.done; });
var notDoneArray = this.todo.filter(function (item) { return !item.done; });
sortedArray = [...notDoneArray, ...doneArray];
return sortedArray;
}
}
});
function moveTaskToDoneTable(item) {
const doneTasksTableBody = document.getElementById('doneTasksTableBody');
const row = document.createElement('tr');
row.innerHTML = `
<td>${item.label}</td>
<td>${item.description}</td>
<td>Done</td>
`;
doneTasksTableBody.appendChild(row);
}
// Function to export table data to Excel
function exportTableToExcel() {
const table = document.querySelector('table'); // Get the table
const rows = table.querySelectorAll('tr'); // Get all rows
const header = [];
const data = [];
// Extract header cells
rows[0].querySelectorAll('th').forEach(headerCell => {
header.push(headerCell.innerText);
});
// Extract table data
for (let i = 1; i < rows.length; i++) {
const rowData = [];
rows[i].querySelectorAll('td').forEach(cell => {
rowData.push(cell.innerText);
});
data.push(rowData);
}
// Create a CSV string with header and data
const csvContent = "" +
header.join(",") +
"\n" +
data.map(row => row.join(",")).join("\n");
// Create a Blob and save it as a file
const blob = new Blob([csvContent], { type: "data:text/csv;charset=utf-8" });
saveAs(blob, "exported_data.csv");
}
// Attach the exportTableToExcel function to the button click event
const saveButton = document.getElementById('save-button');
saveButton.addEventListener('click', exportTableToExcel);
No comments:
Post a Comment