Web Development Project
Web Development Project
Memiliki halaman arahan yang baik untuk situs web Anda adalah penting. Laman landas ini dapat
membantu mengarahkan pelanggan ke situs Anda di mana mereka akan menemukan produk dan
layanan Anda dan mudah-mudahan mengambil tindakan.
Dalam tutorial berbasis teks ini, saya akan memandu Anda tentang cara membuat laman landas
untuk saluran TV tinju dengan HTML, CSS, dan JavaScript.
Nama saluran TV fiksi kita adalah JabTV, dan tujuan pembuatan laman landas adalah untuk
mengumpulkan email.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Kita akan mengkodekan bagian demi bagian dari landing page agar tidak terlalu rumit untuk
dimengerti.
<nav>
<a href="#" class="logo">
<h1>
<span class="jab">Jab</span><span class="tv">TV</span
><span class="fist">👊</span>
</h1>
</a>
</nav>
It’s a combination of the words “Jab” and “TV”, with a punch emoji.
The nav menu items are generic links placed in an unordered list tag, as shown in the snippet
below:
<ul>
<li class="nav-item">
<a href="#about" class="nav-link" id="nav-link">About</a>
</li>
<li class="nav-item">
<a href="#stars" class="nav-link" id="nav-link">Boxing Stars</a>
</li>
<li class="nav-item">
<a href="#stakeholders" class="nav-link" id="nav-link"
>stakeholders</a
>
</li>
<li class="nav-item">
<a href="#sub" class="nav-link" id="nav-link">Subscribe</a>
</li>
</ul>
In addition, we need some bars for the mobile menu. The bars will be hidden on the desktop version
and visible on mobile phones.
For this, I will be using bars made with raw HTML and CSS, not icons. The bars will be span tags
placed in a container div with a class of hamburger.
/* CSS Variables */
:root {
--normal-font: 400;
--bold-font: 600;
--bolder-font: 900;
--primary-color: #0652dd;
--secondary-color: #ea2027;
--line-height: 1.7rem;
--transition: 0.4s ease-in;
}
/* Smooth scroll effect */
html {
scroll-behavior: smooth;
}
/* Resets */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
transition: var(--transition);
}
body {
font-family: "Roboto", sans-serf;
}
ul li {
list-style-type: none;
}
a {
text-decoration: none;
color: var(--primary-color);
}
a:hover {
color: var(--secondary-color);
}
Dalam cuplikan kode CSS di atas, saya menghapus margin dan padding default yang ditetapkan ke
semua elemen oleh browser dan mengatur ukuran kotak menjadi kotak perbatasan. Dengan cara ini
padding dan set margin akan lebih disengaja.
Saya juga mengatur transisi (dideklarasikan dalam variabel) sehingga Anda dapat melihat setiap
transisi di situs web.
Semua tautan akan terlihat berwarna biru dan merah saat diarahkan – berkorelasi dengan warna
primer dan sekunder.
Untuk menata logonya, saya akan membuat <span> pertama menjadi merah, <span> kedua menjadi
biru, dan .fist menjadi merah. Warna merah dan biru masing-masing telah ditetapkan sebagai warna
sekunder dan warna primer dalam variabel CSS.
Warna merah dan biru biasanya digunakan dalam tinju amatir dan olahraga tarung lainnya, itulah
sebabnya saya memilihnya untuk situs web.
.fist {
color: var(--secondary-color);
}
.jab {
color: var(--primary-color);
}
.tv {
color: var(--secondary-color);
}
So far, the navbar looks like this:
To place the logo and menu items side by side, I will be using Flexbox. I will also hide the bars
because we only need them on mobile devices.
nav {
background: #fff;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
box-shadow: 2px 3px 2px #f1f1f1;
}
I applied a box shadow to make sure the user knows where the navbar terminates.
I’m also going to make the navbar sticky, so it always stays at the top whenever the user scrolls
down. This helps create a good user experience.
I will do it with 4 lines of CSS:
position: sticky;
top: 0;
left: 0;
z-index: 1;
To hide the bars, I’m going to target the .hambuger class and give it a display of none:
.hamburger {
display: none;
}
The navbar looks a lot better:
But the logo should be bigger. We also need to make sure the menu items are side by side and not
on top of one another, so Flexbox will be instrumental here again.
.logo {
font-size: 2rem;
font-weight: 500;
}
ul {
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-item {
margin-left: 2rem;
}
.nav-link {
font-weight: var(--bold-font);
}
Take a look at the navbar now:
The HTML for the hero section is in the code snippet below:
<section class="hero">
<div class="intro-text">
<h1>
<span class="hear"> You can Hear the Jabs </span> <br />
<span class="connecting"> Connecting</span>
</h1>
<p>
An online streaming platform for boxing matches <br />
We also dedicate some special time to throwbacks cuz old is
gold
</p>
<a class="btn red" href="#">Learn More</a>
<a class="btn blue" href="#">Subscribe</a>
</div>
<div class="i-frame">
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/sUmM_PFpsvQ"
title="YouTube video player"
frameborder="10"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-
picture"
></iframe>
<div class="stand-1"></div>
<div class="stand-2"></div>
</div>
</section>
display: flex;
align-items: center;
justify-content: space-between;
gap: 1.9rem;
max-width: 1100px;
margin: 2rem auto -6rem;
}
Selain menyelaraskan berbagai hal dengan Flexbox, saya juga memberikan lebar maksimum pada
bagian tersebut sebesar 1100 piksel sehingga pengguna tidak perlu melihat terlalu jauh untuk
melihat konten bagian – ini bagus untuk pengalaman pengguna.
Saya menerapkan margin 2rem di atas, otomatis di kiri dan kanan, dan -6rem di bawah untuk
memusatkan semua yang ada di bagian tersebut.
Sejauh ini, kami memiliki ini di browser:
To style the h1 texts of the hero section, I put them in their respective span tags, so I can style
them differently. Therefore, I will target the texts with the class attributes of the span tags:
.intro-text h1 {
font-size: 3rem;
margin-bottom: 1rem;
}
.intro-text h3 {
margin-bottom: 0.5rem;
}
.hero p {
line-height: var(--line-height);
}
.hear {
color: var(--primary-color);
}
.connecting {
color: var(--secondary-color);
}
Remember there are 2 buttons in the section, so I have a basic style defined for them:
.btn {
margin-top: 1rem;
display: inline-block;
padding: 0.8rem 0.6rem;
border: none;
font-size: 1.4rem;
border-radius: 5px;
color: #fff;
}
.red {
background-color: var(--secondary-color);
margin-right: 1.5rem;
}
.red:hover {
background-color: #f1262d;
color: #fff;
}
.blue {
background-color: var(--primary-color);
}
.blue:hover {
background-color: #095cf7;
color: #fff;
}
The section is taking shape:
Selanjutnya, kita perlu membuat iframe terlihat seperti TV. Properti perbatasan akan membantu
kami menyelesaikannya. Dari HTML ingat saya punya 2 tag div dengan kelas stand-1 dan stand-2.
Saya akan membuat singkatan dari TV jadul dengan 2 tag div dengan menggunakan properti
transform – yang berperan penting dalam memutar atau memiringkan suatu elemen.
iframe {
max-width: 30rem;
border-top: 40px groove var(--primary-color);
border-bottom: 40px groove var(--primary-color);
border-right: 28px solid var(--secondary-color);
border-left: 28px solid var(--secondary-color);
}
.stand-1 {
height: 90px;
width: 6px;
background-color: var(--primary-color);
transform: rotate(40deg);
position: relative;
top: -16px;
left: 200px;
}
.stand-2 {
height: 90px;
width: 6px;
background-color: var(--secondary-color);
transform: rotate(-40deg);
position: relative;
top: -105px;
left: 255px;
}
Untuk dapat memindahkan tribun, saya menggunakan properti posisi dan mengaturnya ke relatif,
yang kemudian membantu saya menetapkan properti kiri dan atas pada tribun.
Bagian pahlawan kini telah terbentuk sepenuhnya:
latar-belakang-warna
gambar-latar belakang
posisi-latar belakang
penutup-latar belakang
pengulangan-latar belakang
latar-belakang-asal
klip-latar belakang
dan background-attachment
Hanya apa yang Anda tentukan yang akan diterapkan, jadi Anda selalu dapat melewatkan salah satu
properti. Selain properti latar belakang, saya juga akan menggunakan Flexbox untuk menyelaraskan
teks dari HTML sehingga dapat terlihat bagus pada gambar latar belakang.
Ini adalah bagaimana saya menggunakan properti posisi dalam kombinasi dengan Flexbox:
.about {
position: relative;
background: url("../images/jab-transformed.png") no-repeat top center/cover;
height: 600px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 1.5rem;
margin: 2rem 0;
}
And this is how the section looks in the browser so far:
To make the texts look readable and nicer, I employed some more CSS:
.about h3 {
font-size: 3em;
margin-bottom: -20px;
}
.about p {
font-size: 1.5em;
}
.about h3 {
text-shadow: 2px 2px 2px #333;
}
.about p {
text-shadow: 2px 2px 2px #333;
font-size: 1.8rem;
}
Take note that I applied text shadow to the texts since they are displayed on an image. You should
do this in every project for better accessibility. The About section looks a lot nicer now:
To make the gallery work and scroll smoothly while viewing the images, you have to initialize it
with one line of JavaScript:
<script>
var lightbox = new SimpleLightbox(".stars-gallery a");
</script>
Our lightbox image gallery is now working:
.stars-gallery {
display: grid;
grid-template-columns: repeat(5, 1fr);
}
In the CSS code snippet above, I targeted the div with a class of stars-gallery and gave it a
display of grid, so we can use other properties of CSS on the elements inside the div.
I defined the column I need with grid-template-columns: repeat(5, 1fr);, which
would confine the images into 5 columns.
So far, this is what the gallery looks like:
More still need to be done, because there is a white space and one of the images is not visible
anymore.
I will give all the images a height and width of 100%, so they can all be visible:
.stars-gallery img,
.stars-gallery a {
width: 100%;
height: 100%;
}
Next, I will target the first image and define a grid row and column for it:
.stars-gallery a:first-child {
grid-row: 1/3;
grid-column: 1/3;
}
With the defined grid row and column, the first image will occupy the first 2 rows horizontally, and
the first 2 columns vertically.
I will also target the second image and define a grid column for it:
.stars-gallery a:nth-child(2) {
grid-column: 3/5;
}
But that’s not how we want it, so we have some styling to do.
.people {
margin-top: 2rem;
padding: 1rem 0;
}
.stakeholders {
margin: 2rem auto;
max-width: 1100px;
}
.stakeholders img {
border-radius: 0.6rem;
}
In the code snippet above, I pushed the section down a little with a margin-top of 2rem. I targeted
the .people class to do this.
The next thing I did was target the .stakeholders class, and I assigned it a margin of 2rem on
the top and bottom. I also centered it on the left and right with auto.
Targeting the .stakeholders class again, I also gave the section a maximum width of 1100px,
so spaces are created on the left and right. This makes sure that the user doesn’t look to the extreme
left and right before seeing things.
This makes things look a little better:
To finally layout the images and text with CSS grid, this is what I did:
.persons {
display: grid;
grid-template-columns: repeat(3, 1fr);
place-items: center;
gap: 1rem;
}
To make the text look better, I’m going to target it with the .name and .role classes and align it
to the center, and then assign it a color and font where necessary:
.name {
color: var(--primary-color);
text-align: center;
}
.role {
color: var(--secondary-color);
text-align: center;
font-size: 0.8rem;
}
The section now looks good enough:
.sub {
margin-top: 2rem;
}
.sub h3 {
text-align: center;
}
form {
text-align: center;
margin: 0.4rem 2rem;
}
Notice I also pushed the section to the bottom a little with a margin of 2rem.
To push the form away from the h3, I gave it a margin of 0.4rem at the top and bottom, and
2rem at the left and right.
The form now looks a lot better:
The next thing we should do is make the input area and subscribe button look better. I attached a
class of .email-sub to the input area, so I’m going to target it with the class and apply some
styling:
.email-sub {
padding: 0.2rem;
border: 1px solid var(--primary-color);
border-radius: 4px;
}
.email-sub:focus {
border: 1px solid var(--secondary-color);
outline: none;
}
Here's what's happening to the input area with the CSS above:
I gave the input a padding of 0.2rem for better spacing
I gave it (the input) a blue solid border of 1px
I made the corners of the input rounded with a border-radius of 4px
when focused, that is when you’re trying to type in the input, I changed the border color to the
website’s secondary color
lastly, I set the outline to none to remove the ugly outline that shows while typing in the input
areas.
I made the subscribe button look better with the CSS below:
.submit-btn {
background-color: var(--primary-color);
color: #fff;
padding: 0.3rem;
margin: 0 0.5rem;
border: none;
border-radius: 2px;
cursor: pointer;
}
.submit-btn:hover {
background-color: #095cf7;
}
<section class="social">
<h3>Connect with us on Social Media</h3>
<div class="socicons">
<a href="#"> <ion-icon name="logo-twitter"></ion-icon> </a>
<a href="#"> <ion-icon name="logo-instagram"></ion-icon> </a>
<a href="#"> <ion-icon name="logo-facebook"></ion-icon> </a>
</div>
</section>
.social {
text-align: center;
margin: 2rem;
}
.socicons {
font-size: 1.3rem;
}
This is how the email subscription section finally looks:
To learn more about Ionic icons, check the readme attached to the project on GitHub.
If you are wondering what © is, that’s the character entity for the © you always see in
website footers. The CSS is all done in 6 lines:
footer {
border-top: 1px solid #f1f1f1;
box-shadow: 0px -2px 3px #f1f1f1;
text-align: center;
padding: 2rem;
}
I applied a border-top and box-shadow to the footer so the upper part of it can correlate with
the navbar.
We'll use the class attributes to style the button, and the ids to select it in our JavaScript file. That’s
how we will do things in the CSS and JavaScript. To make the button visible everywhere and look
good, I’m going to give it a fixed position and increase the width and height. I will also give it a
cursor of pointer, so the user knows what is happening when they hover their cursor on it.
.scroll-up {
position: fixed;
right: 0.5%;
bottom: 3%;
cursor: pointer;
}
.up-arrow {
width: 3rem;
height: 3rem;
}
scrollUp.addEventListener("click", () => {
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth",
});
});
We now have a complete website! But let’s take things a little further by adding a dark and light
theme switcher, since a lot of people now enjoy using websites in dark mode.
<div class="theme-switch">
<input type="checkbox" class="checkbox" id="checkbox" />
<label for="checkbox" class="label">
<ion-icon name="partly-sunny-outline" class="sun"></ion-icon>
<ion-icon name="moon-outline" class="moon"></ion-icon>
<div class="switcher"></div>
</label>
</div>
Next, I’m going to position the label relative, center everything in it with Flexbox, and give it a
dark background. With this and some other minor stylings, the dark theme switcher will be more
visible.
.label {
width: 50px;
height: 29px;
background-color: #111;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 30px;
padding: 6px;
position: relative;
}
All you see now is a dark background. Don’t worry. Everything will become visible again.
Remember the div with a class of switcher? Let’s make it white and round to truly look like a
ball. We will also position it absolute because its inside the label which has been positioned
relative.
.switcher {
background-color: #fff;
position: absolute;
top: 5px;
left: 2px;
height: 20px;
width: 20px;
border-radius: 50%;
}
Defining width, height, and a border-radius of 50% is how you make anything round in CSS.
Our dark theme switcher is taking shape, but let’s make the icons visible by giving them the
appropriate colors of reddish for sun and yellowish for moon.
.moon {
color: #ffa502;
}
.sun {
color: #ff4757;
}
Finally, to be able to move the ball left and right, we need to use the :checked pseudo-class on our
checkbox, and target the ball with a class of switcher, then use the transform property to move it by
setting a figure in pixels:
Our ball is now moving and the icons are correctly showing:
What we need to do now is use JavaScript to toggle between the light and dark mode and set the
colors for dark mode.
You can find the color set for our dark theme in the snippet below:
body.dark {
background-color: #1e272e;
}
body.dark .bar {
background-color: #fff;
}
body.dark p {
color: #fff;
}
body.dark h3 {
color: #fff;
}
body.dark nav {
background-color: #1e272e;
box-shadow: 2px 3px 2px #111010;
}
body.dark ul {
background-color: #1e272e;
}
body.dark .name {
color: var(--primary-color);
}
body.dark .role {
color: var(--secondary-color);
}
body.dark footer {
color: #fff;
border-top: 1px solid #111010;
box-shadow: 0px -2px 3px #111010;
}
And here’s how I used JavaScript to toggle the body.dark class by using change event on the
checkbox and the toggle() method of DOM:
const checkbox = document.querySelector("#checkbox");
checkbox.addEventListener("change", () => {
// Toggle website theme
document.body.classList.toggle("dark");
});
Notice that I selected the checkbox with an id of #checkbox and assigned it to
a checkbox variable. Try to always use ids for JavaScript and classes for CSS, so you don’t get
confused.
Users can nohw toggle light and dark modes on our landing page:
ul {
background-color: #fff;
flex-direction: column;
position: fixed;
left: 100%;
top: 5rem;
width: 100%;
text-align: center;
}
ul.active {
left: 0;
}
The nav items have become poorly spaced:
To make sure the nav menu items are well-spaced, I’m going to target them with the .nav-
item class and give them some margins:
.nav-item {
margin: 2rem 0;
}
The CSS snippet above gives each nav menu item a margin of 2rem on the top and bottom, and 0
on the left and right, so they look like this:
There’s one more thing to do with the bars – we need to make sure they change to an X shape when
they are clicked, and back to the bars when clicked again.
To do this, we will attach a class of active to the hamburger menu, and then rotate the bars.
Remember that this active class will be toggled by JavaScript.
.hamburger.active .bar:nth-child(2) {
opacity: 0;
}
.hamburger.active .bar:nth-child(1) {
transform: translateY(10px) rotate(45deg);
}
.hamburger.active .bar:nth-child(3) {
transform: translateY(-10px) rotate(-45deg);
}
function openMenu() {
hamburger.classList.toggle("active");
navMenu.classList.toggle("active");
}
But there’s a problem. The menu items are not hidden any time one of them is clicked. We need to
make this happen for a better user experience.
To do this, we need some JavaScript again. We will:
select all the nav items with querySelectorAll() by targeting their ids
listen for a click event on each of the nav menu items with the forEach() array method
write a function to remove the .active class – which will eventually return the nav menu to
its original state.
const navLink = document.querySelectorAll("#nav-link");
If you noticed, other parts of the website are not looking good on mobile devices. There’s even an
annoying horizontal scrollbar. This is not 1998 but 2022!
Adding the following styles to the media query will fix it:
.logo {
font-size: 1.5rem;
}
.hero {
flex-direction: column;
max-width: 500px;
}
.intro-text h1 {
font-size: 2.3rem;
}
.btn {
padding: 0.5rem;
font-size: 1.2rem;
}
iframe {
max-width: 26rem;
}
.stand-1 {
left: 170px;
}
.stand-2 {
left: 225px;
}
.about {
text-align: center;
}
.persons {
grid-template-columns: repeat(1, 1fr);
}
}
With the CSS above, I reduced sizes, changed the direction to column where necessary so the
sections stack on top of one another, and made the TV stands aligned properly.
To make the landing page responsive on smaller phones, I will integrate few changes on mobile
devices of screen width 420px and below:
@media screen and (max-width: 420px) {
.hero {
max-width: 330px;
}
.intro-text h1 {
font-size: 2rem;
}
iframe {
max-width: 330px;
}
.stand-1 {
left: 140px;
}
.stand-2 {
left: 195px;
}
}
We now have a fully responsive landing page:
Grab the finished copy of the landing page code from this Github repo.
Conclusion
In this detailed tutorial, you have learned how to make a:
fully responsive website
dark theme switcher
hamburger menu
lightbox image gallery
scroll-to-top button.
These are functionalities you can always integrate into a new or existing project, so feel free to
always come back to this article any time you need it.
If you find this text-based tutorial helpful, share it by tweeting a thanks or pasting the link on your
social media platforms.
Thank you for reading!