Clash of Clans Navbar Clone Using HTML, CSS, and JavaScript

Faraz

By Faraz -

Learn how to create a Clash of Clans style navbar using HTML, CSS, and JavaScript. Step-by-step guide for beginners with code examples.


clash-of-clans-navbar-clone-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

Navigation bars are a key part of any website, as they guide users to different pages easily. If you are a fan of Clash of Clans, you might have noticed their bold and attractive top menu design. In this tutorial, we will recreate a Clash of Clans style navigation bar using HTML, CSS, and JavaScript.

This project is beginner-friendly and will help you improve your front-end development skills while learning how to style and add interactive effects to a navbar.

Prerequisites

Before you start, make sure you know:

  • Basic HTML (for structure)
  • Basic CSS (for styling)
  • Basic JavaScript (for adding simple animations or effects)
  • A code editor like VS Code
  • A web browser like Google Chrome

Source Code

Step 1 (HTML Code):

We will start with a simple HTML file containing a navigation bar with menu links. Let’s break down the HTML code step by step:

1. Document Structure & Head Section

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Clash of Clans Navbar Clone</title>
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="styles.css">
</head>
  • <!DOCTYPE html> → Declares the HTML document type as HTML5.
  • <html lang="en"> → Sets the document language to English.
  • <meta charset="UTF-8"> → Ensures the page supports all common characters (UTF-8 encoding).
  • <meta name="viewport" ...> → Makes the page responsive on mobile devices by scaling the content.
  • <title> → Page title shown in the browser tab ("Clash of Clans Navbar Clone").
  • Google Fonts link → Loads the "Poppins" font with multiple weights.
  • CSS file link → Loads external stylesheet styles.css for styling.

2. Main Container Start

<body>
    <div id="main">
  • <body> → Contains all the visible content for the webpage.
  • <div id="main"> → Main wrapper div for the entire page structure.

3. Sidebar Header Menu

<div class="sidebar-header-menu">
    <div class="sidebar-menu-container">
  • <div class="sidebar-header-menu"> → The main sidebar container (hidden or shown based on menu button click).
  • <div class="sidebar-menu-container"> → Inner container that holds all sidebar content.

4. Sidebar Menu Header

<div class="sidebar-menu-header">
    <a href="#">
        <img alt="clashofclans" width="63" height="54" src=".../shield.png">
    </a>
    <button id="closeBtn" class="sidebar-close-button">
        <div class="sidebar-exit-icon"></div>
    </button>
</div>
  • Game Logo Image → Clickable logo that links to the homepage.
  • Close Button (closeBtn) → Closes the sidebar when clicked.
  • .sidebar-exit-icon → Placeholder div for an exit icon (styled via CSS).

5. User Profile Section in Sidebar

<a class="sidebar-user-link" href="#">
    <div>
        <div class="sidebar-user-details">
            <div class="sidebar-user-avatar sidebar-avatar-size" data-after-content="f">
                <img alt="avatar" class="image-avatar" src=".../user.png">
                <img alt="SCID icon" width="10" height="8" class="sidebar-scid-icon" src=".../icon-id.svg">
            </div>
            <div>faraz</div>
        </div>
    </div>
    <svg width="7" height="12">...</svg>
</a>
  • sidebar-user-link → Wraps the whole user profile clickable area.
  • User Avatar & Badge → Displays profile picture and SCID icon.
  • Username ("faraz") → Shows the logged-in user’s name.
  • Arrow SVG → Indicates it’s clickable for more options.

6. ID Rewards Link

<a href="#" target="_blank" class="idr-container">
    <div class="idr-left">
        <img alt="ID Rewards" width="37" height="37" class="idr-image" src=".../icon-gradient-id.svg">
        <div class="idr-text">
            <h3 class="idr-title">ID Rewards</h3>
        </div>
    </div>
    <svg width="7" height="12">...</svg>
</a>
  • idr-container → Link to the ID Rewards section.
  • Reward Icon + Text → Shows an icon and "ID Rewards" title.
  • Right Arrow SVG → Indicates navigation.

7. Sidebar Navigation Links

<ul class="sidebar-menu-list">
    <li><a class="sidebar-nav-link" target="_blank" href="#">...</a></li>
    <li><a class="sidebar-nav-link" href="#">...</a></li>
</ul>
  • Unordered List → Holds sidebar navigation links.
  • Each <li> → Contains a clickable link with:
    • SVG icon
    • Text label
    • Right arrow icon

8. Language Selector (Mobile & Desktop)

<div class="menu-language-country">
    <div class="dropdown language-selector ...">
        <div class="dropdown-select-mobile">...</div>
        <div class="dropdown-select-desktop">...</div>
    </div>
</div>
  • Language Selector → Allows the user to switch website language.
  • Mobile Dropdown → Uses <select> element.
  • Desktop Dropdown → Uses a custom dropdown menu with clickable options.
  • Language Globe Icon → Visual indicator for language settings.

9. Country Selector

<div class="menu-country">
    <svg width="16" height="24">...</svg>
    <div>India</div>
</div>
  • Country Icon → Small location pin icon.
  • Country Name ("India") → Shows the user’s selected country.

10. Sticky Header

<div class="sticky-header clashofclans-header">
    <header class="main-header clashofclans-header">
        <div class="header-bg" style="background-image:url(.../topbar-bg.png)"></div>
        <div class="header-content">
            <a class="header-logo" href="#"><img alt="clashofclans" src=".../logo.png"></a>
            <div class="header-nav-buttons">
                <div class="header-cart cart-button">...</div>
                <button id="menuBtn" class="menu-button">...</button>
            </div>
        </div>
    </header>
</div>
  • Sticky Header → Remains fixed at the top of the screen.
  • Game Logo → Clickable link to homepage.
  • Cart Button → Opens sidebar cart.
  • Menu Button (menuBtn) → Opens sidebar navigation.
  • Header Background Image → Decorative top bar background.

Step 2 (CSS Code):

We will style the navbar to look similar to Clash of Clans. Let’s break down the CSS code step by step:

1. Global Styles & Variables

:root {
    --game-theme: #f9f9f9
}
  • Defines a CSS variable for the theme color.
html {
    box-sizing: border-box;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    min-height: 100%;
    scroll-behavior: smooth !important;
}
  • box-sizing: makes padding and border included in element’s size.
  • Font smoothing for crisper text.
  • scroll-behavior: smooth → smooth page scrolling.
*, :after, :before {
    box-sizing: inherit;
}
  • Makes all elements use the same box-sizing as <html>.
body {
    position: relative;
    font-family: Poppins, sans-serif;
    font-size: 20px;
    line-height: 1.5;
    overscroll-behavior-y: none;
    margin: 0;
    width: 100vw;
    overflow-x: hidden;
    background-color: #f9f9f9;
}
  • Sets font, prevents horizontal scroll, and applies theme background.

2. Text & Form Resets

h1,h2,h3,h4,h5,h6,p { margin: 0; padding: 0; font-size: 20px; }
a { color: inherit; }
input, button { appearance: none; }
button {
    background: none;
    border: none;
    font: inherit;
    cursor: pointer;
}
  • Removes default margins, padding, link colors, and button styles.

3. Main Layout

#main {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}
  • #main stretches full screen height.

4. Sticky Header

.sticky-header {
    position: sticky;
    top: 0;
    z-index: 20;
    will-change: transform;
}
  • Header stays visible on scroll.

5. Header & Navigation

.header-content {
    display: flex;
    justify-content: space-between;
    max-width: 1200px;
    gap: 8px;
}
.header-logo { height: 54px; cursor: pointer; }
.header-nav-buttons {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-left: auto;
}
  • Flex layout for logo and navigation buttons.
  • Responsive gap adjustments.

6. Menu Button States

.menu-button.logged-in {
    background: linear-gradient(...);
    border-radius: 999px;
    padding: 2px 10px 2px 2px;
}
  • Shows a rounded gradient button for logged-in users.

7. Sidebar Menu

.sidebar-menu-container {
    position: fixed;
    top: 0; right: 0;
    width: 100vw; height: 100vh;
    background-color: #fff;
    z-index: 30;
    overflow-y: auto;
}
  • Fullscreen off-canvas sidebar menu.
  • Contains:
    • .sidebar-menu-header (top bar with close button)
    • .sidebar-menu-content (menu links)
    • .sidebar-user-link (user info)

8. Dropdown Menu

.dropdown {
    position: relative;
}
.dropdown-options {
    display: none;
    position: absolute;
    top: calc(100% + 16px);
    background: #fff;
    border-radius: 16px;
    box-shadow: 0 2px 16px rgba(71,69,156,.05);
    opacity: 0;
    transform: translateY(15px);
    transition: opacity .25s ease, transform .25s ease;
}
.dropdown-options.show {
    opacity: 1;
    transform: translateY(0);
}
  • Hidden by default, fades/slides down when .show is applied.

9. Language Selector

.language-selector {
    display: flex;
    border: 1px solid #fff;
    border-radius: 4px;
    padding: 0 8px;
}
.language-selector-mobile-nav {
    border: 1px solid #666;
    color: #666;
}
  • Styled dropdown for choosing language.
  • Different look for desktop vs mobile.

10. Backdrop Overlays

.menu-backdrop,
.cart-backdrop {
    position: fixed;
    top:0; left:0; right:0; bottom:0;
    background-color: rgba(0,0,0,.65);
    backdrop-filter: blur(1px);
}
  • Dark transparent layer behind modals or sidebars.

11. Cart Sidebar

.sidebar-cart {
    display: none;
}
.sidebar-cart.show {
    display: flex;
}
.sidebar-cart-header {
    background-color: #000;
    color: #fff;
    position: sticky;
    top: 0;
}
  • Shopping cart appears as right-side panel with sticky black header.

12. Responsive Media Queries

@media(min-width:64em) { ... }
@media(min-width:112.5em) { ... }
@media(min-width:50em) { ... }
@media(max-width:45.99em) { ... }
  • 64em (~1024px): Adjusts header/logo size, desktop-only dropdowns.
  • 112.5em (~1800px): Increases header height for large screens.
  • 50em (~800px): Adjust nav button size.
  • <46em (~736px): Sidebar takes full width.
  • <64em (~1024px): Adds padding for mobile menu content.
:root {
    --game-theme: #f9f9f9
}

html {
    box-sizing: border-box;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    min-height: 100%;
    scroll-behavior: smooth !important
}

*,
:after,
:before {
    box-sizing: inherit
}

body {
    position: relative;
    color: #191919;
    font-family: Poppins, sans-serif;
    font-size: 20px;
    line-height: 1.5;
    overscroll-behavior-y: none;
    scroll-behavior: smooth;
    margin: 0;
    min-height: 100%;
    width: 100vw;
    overflow-x: hidden;
    background-color: #f9f9f9
}

h1,
h2,
h3,
h4,
h5,
h6,
p {
    margin: 0;
    padding: 0;
    font-size: 20px
}

a {
    color: inherit
}

input {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none
}

button {
    background: none;
    color: inherit;
    border: none;
    padding: 0;
    font: inherit;
    cursor: pointer;
    outline: inherit
}

#main {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    height: 100%;
}

.sticky-header {
    position: -webkit-sticky;
    position: sticky;
    top: 0;
    width: 100%;
    z-index: 20;
    will-change: transform;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden
}

.sticky-header.clashofclans-header {
    margin-bottom: -24px
}

.main-header.clashofclans-header .header-content {
    padding: 0 0 8px
}

.header-content {
    display: flex;
    flex-direction: row;
    width: 100%;
    max-width: min(100%, 1200px);
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 0;
    z-index: 1
}

.menu-button.clashofclans-header.logged-in {
    background: linear-gradient(141.48deg, #d6c6b1 3.23%, #c3ac94 92.61%)
}

.clashofclans-header .header-bg {
    background-repeat: repeat-x;
    background-size: contain;
    background-position: 100% 0
}

.clashofclans-header .header-logo {
    aspect-ratio: 7/6;
    margin-left: 8px
}

.main-header {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 80px
}

.main-header .header-bg {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    filter: drop-shadow(0 10px 4px rgba(0, 0, 0, .3));
    transform: translateZ(0)
}

.header-logo {
    position: relative;
    display: flex;
    align-items: flex-end;
    order: 0;
    cursor: pointer;
    height: 54px
}

.header-logo img {
    position: absolute;
    height: 100%;
    width: 100%;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    color: transparent;
}

.header-nav-buttons {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-left: auto;
    padding-bottom: 4px;
    padding-right: 16px;
    z-index: 3
}

.header-nav-buttons .header-cart {
    order: 1;
    height: 100%;
    margin-left: auto;
    color: #000
}

.header-nav-buttons .menu-button {
    display: flex;
    align-items: center;
    order: 2
}

.header-nav-buttons .menu-button.logged-in {
    height: 38px;
    column-gap: 8px;
    color: #000;
    background: linear-gradient(141.48deg, #d6c6b1 3.23%, #c3ac94 92.61%);
    mix-blend-mode: normal;
    box-shadow: inset 0 1px 0 rgba(0, 0, 0, .1);
    border-radius: 999px;
    box-shadow: inset 0 -1px 0 hsla(0, 0%, 100%, .4), inset 0 1px 0 rgba(0, 0, 0, .15);
    padding: 2px 10px 2px 2px
}

.header-nav-buttons .menu-button.clashofclans-header.logged-in {
    background: linear-gradient(141.48deg, #d6c6b1 3.23%, #c3ac94 92.61%)
}

.header-nav-buttons .menu-button .menu-avatar {
    width: 32px;
    height: 32px;
    flex-shrink: 0
}

.header-nav-buttons .menu-button .menu-icon {
    width: 32px;
    height: 32px
}

.header-nav-buttons .menu-button .menu-icon g,
.header-nav-buttons .menu-button .menu-icon>svg>path {
    fill: #000
}

.cart-button {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center
}

.cart-button svg>path {
    fill: rgba(0, 0, 0, 0)
}

.icon-close-button {
    height: 24px;
    width: 24px;
    display: inline-block;
    margin: 0 auto;
    cursor: pointer
}

.cart-icon {
    height: 28px;
    width: 28px;
    margin-bottom: 3px
}

.cart-icon:after {
    content: attr(data-after-content);
    text-transform: uppercase;
    border-radius: 4px;
    position: absolute;
    height: 18px;
    width: 18px;
    background: linear-gradient(135deg, rgb(255, 181, 23), rgb(255, 207, 113));
    color: #fff;
    top: calc(50% + 5px);
    left: calc(50% + 6px);
    font-weight: 400;
    font-size: 12px;
    line-height: 1.5;
    display: flex;
    justify-content: center;
    align-items: center
}

.sidebar-user-avatar {
    height: 100%;
    width: 100%;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center
}

.sidebar-user-avatar .image-avatar {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    box-sizing: border-box
}

.sidebar-user-avatar:hover {
    cursor: pointer
}

.sidebar-header-menu {
    z-index: 35
}


.sidebar-menu-container {
    position: fixed;
    display: flex;
    flex-direction: column;
    margin: 0;
    top: 0;
    right: 0;
    width: 100vw;
    height: 100vh;
    background-color: #fff;
    z-index: 30;
    overflow-y: auto
}

.sidebar-menu-header {
    width: 100%;
    height: 80px;
    padding: 0 16px 0 8px;
    display: flex;
    align-items: center;
    justify-content: space-between
}

.sidebar-close-button {
    width: 48px;
    height: 48px
}

.sidebar-close-button g,
.sidebar-close-button>svg>path {
    fill: #000
}

.sidebar-exit-icon {
    background-image: url(https://raw.githubusercontent.com/farazc60/Project-Images/refs/heads/main/coc-navbar-clone/icon-exit.svg);
    transition: background-image .2s cubic-bezier(.645, .045, .355, 1) 0s;
    background-position: 50%;
    background-repeat: no-repeat;
    width: 100%;
    height: 100%
}

.sidebar-exit-icon:hover {
    background-image: url(https://raw.githubusercontent.com/farazc60/Project-Images/refs/heads/main/coc-navbar-clone/icon-exit-gray.svg)
}

.sidebar-menu-content {
    position: relative;
    display: flex;
    height: 100%;
    width: 100%;
    overflow-y: auto;
    flex-direction: column;
    justify-content: space-between;
    gap: 24px;
    overscroll-behavior: contain;
    padding: 32px;
    background-color: #fafafa;
    transform: translateZ(0);
    -webkit-transform: translateZ(1000px)
}

.sidebar-menu-links {
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 24px
}

.sidebar-menu-links .sidebar-menu-list {
    display: flex;
    flex-direction: column;
    gap: 24px;
    padding: 0;
    margin: 0;
    list-style: none;
    font-family: Poppins, system-ui, sans-serif;
    font-weight: 400;
    font-size: 14px;
    line-height: 1.5
}

.sidebar-menu-links .sidebar-nav-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    text-decoration: none;
    color: #000
}

.sidebar-menu-links .sidebar-nav-link div:first-child {
    display: flex;
    align-items: center;
    gap: 16px
}

.sidebar-menu-links .menu-nav-bottom-links {
    margin-top: auto
}

.sidebar-menu-links .menu-language-country {
    display: flex;
    justify-content: space-between;
    margin-top: auto;
    font-weight: 400;
    font-size: 12px;
    line-height: 1.5
}

.sidebar-menu-links .menu-language-country .menu-country {
    grid-area: country;
    justify-self: flex-end;
    align-self: flex-end;
    padding-top: 4px;
    padding-bottom: 8px;
    gap: 8px;
    color: gray;
    display: flex;
    justify-content: center;
    align-items: center
}

.sidebar-menu-links .menu-language-country .menu-country path {
    stroke: gray;
    fill: none
}

.sidebar-user-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    text-decoration: none;
    font-family: Poppins, system-ui, sans-serif;
    font-weight: 400;
    font-size: 14px;
    line-height: 1.5
}

.sidebar-user-link .sidebar-user-details {
    display: flex;
    gap: 16px;
    align-items: center
}

.sidebar-user-link .sidebar-avatar-size {
    --size: 37px;
    height: var(--size);
    width: var(--size)
}

.sidebar-scid-icon {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 20px;
    height: 20px;
    z-index: 1
}

.idr-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    text-decoration: none
}

.idr-left {
    display: flex;
    align-items: center
}

.idr-image {
    border-radius: 50%
}

.idr-text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin-left: 16px
}

.idr-title {
    font-family: Poppins, system-ui, sans-serif;
    font-weight: 400;
    font-size: 14px;
    line-height: 1.5
}

.dropdown {
    position: relative
}

.dropdown p {
    color: #fff;
    margin: 0
}

.dropdown .dropdown-main {
    display: flex;
    align-items: center
}

.dropdown .dropdown-main:hover {
    cursor: pointer
}

.dropdown path {
    fill: gray
}

.dropdown-options {
    display: none;
    flex-direction: column;
    position: absolute;
    top: calc(100% + 16px);
    left: 0;
    width: 223px;
    padding: 8px 0;
    background-color: #fff;
    z-index: 25;
    -webkit-overflow-scrolling: touch;
    border-radius: 16px;
    box-shadow: 0 2px 16px rgba(71, 69, 156, .05);
    overflow-y: auto;
    opacity: 0;
    transform: translateY(15px);
    transition: opacity 0.25s ease, transform 0.25s ease;
    will-change: opacity, transform;

}

.dropdown-options.show {
    opacity: 1;
    transform: translateY(0);
}

.dropdown-options ::-webkit-scrollbar,
.dropdown-options ::-webkit-scrollbar-track {
    border-radius: 16px;
    width: 8px
}

.dropdown-options ::-webkit-scrollbar-thumb {
    border-radius: 12px;
    background-color: #ccc
}

.dropdown-option {
    opacity: 1;
    transition: color .4s;
    margin-bottom: 0
}

.dropdown-option a,
.dropdown-option p {
    color: #666;
    transition: color .4s;
    text-decoration: none
}

.dropdown-option a:active,
.dropdown-option a:hover,
.dropdown-option p:active,
.dropdown-option p:hover {
    color: #191919
}

.dropdown-label {
    text-decoration: none;
    color: gray;
    transition: color .2s;
    border-bottom: 1px solid #f2f2f2;
    padding: 0 16px;
    display: flex;
    align-items: center;
    height: 44px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap
}

.dropdown-option:last-child>.dropdown-label {
    border-bottom: none
}

.dropdown-up .dropdown-options {
    bottom: calc(100% + 16px);
    left: 0;
    top: unset
}

.dropdown-container {
    overflow: auto
}

.dropdown-active {
    color: #191919 !important;
    font-weight: 800 !important;
}

.language-selector {
    display: flex;
    max-width: -moz-fit-content;
    max-width: fit-content;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    min-height: 32px;
    flex-direction: row;
    flex-wrap: nowrap;
    color: #fff;
    border: 1px solid #fff;
    border-radius: 4px;
    padding: 0 8px
}

.language-selector button,
.language-selector label {
    min-width: 120px;
    display: flex;
    justify-content: flex-start;
    align-items: center
}

.language-selector .language-selector-label-text {
    margin-right: auto;
    font-family: Poppins, system-ui, sans-serif;
    font-weight: 400;
    font-size: 12px;
    line-height: 1.5
}

.language-selector .language-selector-globe-icon {
    align-self: center
}

.language-selector .language-selector-globe-icon path {
    fill: rgba(0, 0, 0, 0);
    stroke: #fff
}

.language-selector.language-selector-mobile-nav {
    border: 1px solid #666;
    color: #666
}

.language-selector.language-selector-mobile-nav .language-selector-label-text {
    color: #000
}

.language-selector.language-selector-mobile-nav .language-selector-label-text path {
    fill: rgba(0, 0, 0, 0);
    stroke: #000
}

.language-selector.language-selector-mobile-nav .language-selector-globe-icon {
    width: 20px;
    height: 20px
}

.language-selector.language-selector-mobile-nav .language-selector-globe-icon path {
    fill: rgba(0, 0, 0, 0);
    stroke: #000
}

.language-selector.language-selector-mobile-nav span>svg>g>path {
    fill: #000
}

.language-selector.language-selector-mobile-nav:hover,
.language-selector.language-selector-mobile-nav:hover .language-selector-label-text {
    color: #000
}

.language-selector.language-selector-mobile-nav:hover .language-selector-globe-icon path {
    stroke: #000
}

.language-selector.language-selector-mobile-nav:hover span>svg>g>path {
    fill: #000
}

.language-selector.language-selector-mobile-nav.language-selector-storefront {
    border: none;
    padding: 0
}

.language-selector.language-selector-mobile-nav.language-selector-storefront .language-selector-label-text {
    margin-right: 0;
    font-family: Poppins, system-ui, sans-serif;
    font-weight: 400;
    font-size: 12px;
    line-height: 1.5
}

.dropdown-select-desktop path,
.dropdown-select-mobile path {
    fill: #fff
}

.dropdown-select-desktop button,
.dropdown-select-mobile button {
    color: #fff
}

.dropdown-select-desktop {
    display: none
}

.dropdown-select-desktop .dropdown-main {
    gap: 8px;
    font-family: Poppins, system-ui, sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 1.5
}

.dropdown-select-mobile label {
    display: flex;
    gap: 8px;
    position: relative;
    color: #fff
}

.dropdown-label,
.dropdown-option,
.dropdown-select {
    cursor: pointer;
    font-family: Poppins, system-ui, sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 20px
}

.dropdown-select-mobile .dropdown-select {
    left: 0;
    top: 0;
    position: absolute;
    height: 100%;
    width: 100%;
    opacity: 0
}

.arrow {
    transition: transform .2s cubic-bezier(.55, .055, .675, .19);
    display: flex;
    justify-content: center;
    align-items: center
}

.arrow-down {
    transform: rotate(0deg)
}

.arrow-up {
    transform: rotate(-180deg)
}

.menu-backdrop {
    z-index: 29;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background-color: rgba(0, 0, 0, .65);
    backdrop-filter: blur(1px);
    -webkit-backdrop-filter: blur(1px);
    transform: translateZ(0);
    overflow-y: auto
}

.sidebar-header-menu,
.sidebar-cart {
    display: none;
}

.sidebar-header-menu.show,
.sidebar-cart.show {
    display: flex;
}

.sidebar-container {
    display: flex;
    flex-direction: column;
    background-color: #fff;
    width: 100%;
    height: 100%;
    position: fixed;
    right: 0;
    top: 0;
    z-index: 30;
    overflow: hidden;
}

.sidebar-cart-flex {
    display: flex;
    flex-direction: column;
}

.sidebar-cart-header {
    background-color: #000;
    color: #fff;
    padding: 17.6px 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: -webkit-sticky;
    position: sticky;
    top: 0;
    z-index: 30;
    transform: translateZ(0);
    -webkit-transform: translateZ(0) translateZ(1000px);
}

.sidebar-cart-header>div {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
}

.sidebar-cart-header p {
    font-family: Poppins, system-ui, sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 1.5;
}

.sidebar-cart-header button {
    margin: 0;
}

.empty-cart-container {
    background: radial-gradient(74.62% 28.67% at 50% 55.92%, #ffffff 0, rgba(255, 255, 255, 0) 100%), #f2f2f2;
    height: 100%;
    display: flex;
    align-items: center;
    flex-direction: column;
    padding-top: 72px;
    gap: 16px;
}

.empty-cart-container p {
    color: #909090;
    max-width: 260px;
    text-align: center;
    font-size: 34px;
    line-height: 1;
    margin-bottom: -100px;
}

.cart-backdrop {
    z-index: 1;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background-color: rgba(0, 0, 0, .65);
    backdrop-filter: blur(1px);
    -webkit-backdrop-filter: blur(1px);
    transform: translateZ(0);
}


@media(min-width:64em) {
    .header-content {
        gap: 16px;
    }

    .clashofclans-header .header-logo {
        width: 160px;
        height: 78px;
        margin: 0;
    }

    .clashofclans-header .header-logo img {
        height: auto;
    }

    .clashofclans-header {
        height: 100px;
        justify-content: flex-start;
    }

    .sidebar-header-menu {
        z-index: 30;
    }

    .sidebar-menu-container {
        width: 40%;
        max-width: 400px;
        min-width: 300px;
    }

    .dropdown {
        display: flex;
        justify-content: center;
        align-items: center
    }

    .language-selector {
        color: gray;
        min-height: 38px
    }

    .language-selector .language-selector-label-text {
        margin-right: auto;
        font-family: Poppins, system-ui, sans-serif;
        font-weight: 400;
        font-size: 14px;
        line-height: 1.5
    }

    .dropdown-select-desktop {
        display: flex
    }

    .dropdown-select-mobile {
        display: none
    }

    .sidebar-container {
        width: 400px;
    }
}

@media(min-width:112.5em) {
    .main-header {
        padding: 0 16px;
        height: 100px;
    }
}

@media(min-width:50em) {
    .header-nav-buttons {
        width: 160px;
        height: 100%;
        gap: 24px;
        padding-bottom: 0
    }
}

@media (min-width: 46em) {
    .empty-cart-container {
        padding-top: 32px;
    }

    .empty-cart-image img {
        max-width: 300px;
        height: auto;
    }
}

@media(max-width:45.99em) {
    .sidebar-menu-container {
        left: 0
    }
}

@media(max-width:63.99em) {
    .sidebar-menu-content {
        padding-bottom: 112px
    }
} 

Step 3 (JavaScript Code):

We can make the navbar responsive with a simple menu toggle. Let’s break it down step by step:

1. Element Selection

const menu = document.querySelector(".sidebar-header-menu");
const menuBtn = document.getElementById("menuBtn");
const closeBtn = document.getElementById("closeBtn");

const sidebarCart = document.querySelector(".sidebar-cart");
const sidebarCloseBtn = document.getElementById("sidebar-closeBtn");
const bagBtn = document.getElementById("bagBtn");

const dropdownBtn = document.querySelector(".dropdown-main");
const dropdownOptions = document.querySelector(".dropdown-options");
const arrowIcon = dropdownBtn.querySelector(".arrow");

let closingHandler = null;
  • menu → Sidebar menu (header menu) element.
  • menuBtn → Button to open the menu.
  • closeBtn → Button to close the menu.
  • sidebarCart → Cart sidebar element.
  • sidebarCloseBtn → Button to close the cart sidebar.
  • bagBtn → Button to open the cart sidebar.
  • dropdownBtn → The main dropdown trigger button.
  • dropdownOptions → The dropdown list of options.
  • arrowIcon → The arrow icon inside the dropdown (changes direction on toggle).
  • closingHandler → Temporary event handler for closing animation cleanup.

2. Open & Close Element Functions

function openElement(el) {
    el.style.display = "block";
    el.offsetHeight; // forces browser to reflow (needed for animation start)
    el.classList.add("show");
}

function closeElement(el) {
    el.classList.remove("show");
    el.style.display = "none";
}
  • openElement(el)
    • Makes element visible (display: block).
    • Forces a reflow (el.offsetHeight) so CSS animations work correctly.
    • Adds "show" class (triggers CSS transition).
  • closeElement(el)
    • Removes "show" class (hides via CSS animation).
    • Sets display: none to remove it from the layout.

3. Dropdown Open/Close

function openDropdown() {
    if (dropdownOptions.classList.contains("show")) return;
    dropdownOptions.style.display = "flex";
    void dropdownOptions.offsetWidth; // force reflow
    dropdownOptions.classList.add("show");
    arrowIcon.classList.remove("arrow-down");
    arrowIcon.classList.add("arrow-up");
    dropdownBtn.setAttribute("aria-expanded", "true");
}
  • openDropdown()
    • Shows dropdown (display: flex).
    • Forces reflow to restart animation.
    • Adds "show" class (fade/slide animation).
    • Changes arrow from down to up.
    • Sets aria-expanded="true" for accessibility.
function closeDropdown() {
    if (!dropdownOptions.classList.contains("show")) {
        dropdownOptions.style.display = "none";
        return;
    }

    dropdownOptions.classList.remove("show");
    arrowIcon.classList.remove("arrow-up");
    arrowIcon.classList.add("arrow-down");
    dropdownBtn.setAttribute("aria-expanded", "false");

    if (closingHandler) {
        dropdownOptions.removeEventListener("transitionend", closingHandler);
        closingHandler = null;
    }

    closingHandler = function (event) {
        if (event.target === dropdownOptions && event.propertyName === "opacity") {
            dropdownOptions.style.display = "none";
            dropdownOptions.removeEventListener("transitionend", closingHandler);
            closingHandler = null;
        }
    };
    dropdownOptions.addEventListener("transitionend", closingHandler);
}
  • closeDropdown()
  • If already hidden, it just sets display: none.
  • Removes "show" (starts fade-out animation).
  • Changes arrow up → down.
  • Sets aria-expanded="false".
  • Uses a transitionend event to wait until fade-out finishes before hiding (display: none), so there’s no “pop” during animation.

4. Event Listeners

menuBtn.addEventListener("click", () => { openElement(menu); });
closeBtn.addEventListener("click", () => { closeElement(menu); });

bagBtn.addEventListener("click", () => { openElement(sidebarCart); });
sidebarCloseBtn.addEventListener("click", () => { closeElement(sidebarCart); });
  • menuBtn → Opens header sidebar menu.
  • closeBtn → Closes header sidebar menu.
  • bagBtn → Opens cart sidebar.
  • sidebarCloseBtn → Closes cart sidebar.
dropdownBtn.addEventListener("click", (e) => {
    e.stopPropagation(); // stops click from reaching document
    if (dropdownOptions.classList.contains("show")) closeDropdown();
    else openDropdown();
});
  • Clicking the dropdown button toggles between open and close.
document.addEventListener("click", (e) => {
    if (!dropdownBtn.contains(e.target) && !dropdownOptions.contains(e.target)) {
        closeDropdown();
    }
});
  • Clicking anywhere outside the dropdown closes it.
document.addEventListener("keydown", (e) => {
    if (e.key === "Escape") closeDropdown();
})
;
  • Pressing Esc closes dropdown (keyboard accessibility).
const menu = document.querySelector(".sidebar-header-menu");
const menuBtn = document.getElementById("menuBtn");
const closeBtn = document.getElementById("closeBtn");

const sidebarCart = document.querySelector(".sidebar-cart");
const sidebarCloseBtn = document.getElementById("sidebar-closeBtn");
const bagBtn = document.getElementById("bagBtn");

const dropdownBtn = document.querySelector(".dropdown-main");
const dropdownOptions = document.querySelector(".dropdown-options");
const arrowIcon = dropdownBtn.querySelector(".arrow");

let closingHandler = null;

function openElement(el) {
    el.style.display = "block";
    el.offsetHeight;
    el.classList.add("show");
}

function closeElement(el) {
    el.classList.remove("show");
    el.style.display = "none";
}

function openDropdown() {
    if (dropdownOptions.classList.contains("show")) return;
    dropdownOptions.style.display = "flex";
    void dropdownOptions.offsetWidth;
    dropdownOptions.classList.add("show");
    arrowIcon.classList.remove("arrow-down");
    arrowIcon.classList.add("arrow-up");
    dropdownBtn.setAttribute("aria-expanded", "true");
}

function closeDropdown() {
    if (!dropdownOptions.classList.contains("show")) {
        dropdownOptions.style.display = "none";
        return;
    }

    dropdownOptions.classList.remove("show");
    arrowIcon.classList.remove("arrow-up");
    arrowIcon.classList.add("arrow-down");

    dropdownBtn.setAttribute("aria-expanded", "false");

    if (closingHandler) {
        dropdownOptions.removeEventListener("transitionend", closingHandler);
        closingHandler = null;
    }

    closingHandler = function (event) {
        if (event.target === dropdownOptions && event.propertyName === "opacity") {
            dropdownOptions.style.display = "none";
            dropdownOptions.removeEventListener("transitionend", closingHandler);
            closingHandler = null;
        }
    };
    dropdownOptions.addEventListener("transitionend", closingHandler);
}

menuBtn.addEventListener("click", () => {
    openElement(menu);
});
closeBtn.addEventListener("click", () => {
    closeElement(menu);
});

bagBtn.addEventListener("click", () => {
    openElement(sidebarCart);
});
sidebarCloseBtn.addEventListener("click", () => {
    closeElement(sidebarCart);
});

dropdownBtn.addEventListener("click", (e) => {
    e.stopPropagation();
    if (dropdownOptions.classList.contains("show")) closeDropdown();
    else openDropdown();
});

document.addEventListener("click", (e) => {
    if (!dropdownBtn.contains(e.target) && !dropdownOptions.contains(e.target)) {
        closeDropdown();
    }
});

document.addEventListener("keydown", (e) => {
    if (e.key === "Escape") closeDropdown();
});

Final Output:

clash-of-clans-navbar-clone-using-html-css-and-javascript.gif

Conclusion:

By following this tutorial, you learned how to create a Clash of Clans-inspired navigation bar using HTML, CSS, and JavaScript. This project is a fun way to improve your design and coding skills, and you can customize the colors, fonts, and animations to make it unique.

If you enjoyed making this, try adding dropdown menus or animated effects to make your navbar even more interactive.

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 Components

Please allow ads on our site🥺