2022-06-17
html
<!DOCTYPE html>
<html>
<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">
<title>Final Project</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="./css/init.css">
<link rel="stylesheet" href="./css/style.css">
<body>
<!-- header -->
<header>
<div class="container">
<h1>
<button>LOGO</button>
</h1>
<nav>
<ul>
<li>
<button>About</button>
</li>
<li>
<button>Features</button>
</li>
<li>
<button>Portfolio</button>
</li>
<li>
<button>Contact</button>
</li>
</ul>
</nav>
</div>
</header>
<!-- //end header -->
</head>
<!-- main -->
<main id="main"> <!-- 섹션처럼 아이디를 붙여서 쓴다고도 한다 구글에선 -->
<div class="container">
<h4>Welcome</h4>
<!-- 13.10.1에서 span 태그의 내용이 비워집니다. -->
<h2>I`M A <span>Front-End Developer</span></h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium dolor quas nulla unde ea officiis?</p>
<button class="download">DOWNLOAD CV</button>
<button class="mouse"><i class="fa-solid fa-computer-mouse"></i></button>
</div>
</main>
<!-- //end Main -->
<!-- About Me -->
<section id="about" class="about">
<div class="container">
<div class="title">
<h4>Who Am I</h4>
<h2>About Me</h2>
</div>
<div class="about-self">
<div class="left">
<img src="./images/me_alone.jpg" alt="">
</div>
<div class="right">
<h3>Hello, <strong>I`m Sucoding</strong></h3>
<p>I`m Web Publisher And Web Front-End Developer.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe veritatis aperiam accusantium.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Sit praesentium doloremque quos quis est officiis.</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Autem, omnis quibusdam.</p>
<div class="social">
<a href="#">
<i class="fa-brands fa-facebook"></i>
</a>
<a href="#">
<i class="fa-brands fa-instagram"></i>
</a>
<a href="#">
<i class="fa-brands fa-twitch"></i>
</a>
<a href="#">
<i class="fa-brands fa-youtube"></i>
</a>
</div>
</div>
</div>
</div>
</section>
<!-- end About Me -->
<!-- What I Do -->
<section id="features" class="do">
<div class="container">
<div class="title"> <!-- title 영역 앞이랑 유사 -->
<h4>Features</h4>
<h2>What I Do</h2>
</div>
<!-- 사각형 모양으로 3단 분리된 본문 -->
<div class="do-me">
<div class="do-inner"> <!-- 하나의 사각형을 나타내는 do-inner 클래스-->
<div class="icon">
<i class="fa-brands fa-html5"></i>
</div>
<div class="content">
<h3>HTML5</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo culpa magni laboriosam sit excepturi quibusdam adipisci, vero debitis?</p>
</div>
</div>
<div class="do-inner"> <!-- 하나의 사각형을 나타내는 do-inner 클래스-->
<div class="icon">
<i class="fa-brands fa-css3-alt"></i>
</div>
<div class="content">
<h3>CSS3</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo culpa magni laboriosam sit excepturi quibusdam adipisci, vero debitis?</p>
</div>
</div>
<div class="do-inner"> <!-- 하나의 사각형을 나타내는 do-inner 클래스-->
<div class="icon">
<i class="fa-brands fa-bootstrap"></i>
</div>
<div class="content">
<h3>BootStrap v5.0</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo culpa magni laboriosam sit excepturi quibusdam adipisci, vero debitis?</p>
</div>
</div>
</div>
</div>
</section>
<!-- //end What I Do -->
<!-- Background -->
<!-- 배경 영역은 아무런 정보를 전하지 않는 단순히 디자인적 요소이므로 h2~h6 태그를 사용할 필요가 없습니다.
section 태그 대신에 div 태그를 사용했음. -->
<div class="bg"></div>
<!-- //end Background-->
<!-- PortFolio -->
<!-- what_i_do 영역과 유사 -->
<section id="portfolio" class="portfolio">
<div class="container">
<div class="title">
<h4>PORTFOLIOBACK</h4>
<h2>PortFolio</h2>
</div>
<div class="portfolio-me">
<div class="portfolio-inner">
<img src="images/mock1.png" alt="">
<strong>BRANDING</strong>
<h3>Package Design</h3>
</div>
<div class="portfolio-inner">
<img src="images/mock2.png" alt="">
<strong>DEVELOPMENT</strong>
<h3>Tablet App Dev</h3>
</div>
<div class="portfolio-inner">
<img src="images/mock3.png" alt="">
<strong>MARKETING</strong>
<h3>Coka Cola </h3>
</div>
<div class="portfolio-inner">
<img src="images/mock4.png" alt="">
<strong>APP</strong>
<h3>FaceBook Clone</h3>
</div>
<div class="portfolio-inner">
<img src="images/mock5.png" alt="">
<strong>APP</strong>
<h3>Netflix Clone</h3>
</div>
<div class="portfolio-inner">
<img src="images/mock6.png" alt="">
<strong>WEB</strong>
<h3>FirmBee Web</h3>
</div>
</div>
</div>
</section>
<!-- //end PortFolio -->
<!-- Contact With Me -->
<section id="contact" class="contact">
<div class="container">
<div class="title">
<h4>CONTACT</h4>
<h2>Contact With Me</h2>
</div>
<!-- Contact With Me 영역의 본문은 크게 왼쪽(phone, email, address)과 오른쪽(입력 양식 폼)으로 나눌 수 있습니다. 그래서 다음과 같이 contact-me 클래스를 가지는 div 태그 안에 left 클래스를 가지는 div 태그와 right 클래스를 가지는 div 태그로 영역을 구분합니다. -->
<div class="contact-me">
<div class="left">
<div class="card">
<div class="icon">
<i class="fa-solid fa-phone-volume"></i>
</div>
<div class="info-text">
<h3>phone</h3>
<p>010-2222-1111</p>
</div>
</div>
<div class="card">
<div class="icon">
<i class="fa-solid fa-envelope-open-text"></i>
</div>
<div class="info-text">
<h3>email</h3>
<p>sucoding@naver.com</p>
</div>
</div>
<div class="card">
<div class="icon">
<i class="fa-solid fa-location-crosshairs"></i>
</div>
<div class="info-text">
<h3>address</h3>
<p>Samseong-ro, Gangnam-gu, Seoul, Republic of Korea</p>
</div>
</div>
</div>
<div class="right">
<form action="#">
<div class="form-group">
<label for="name">name</label>
<input type="text" id="name">
</div>
<div class="form-group">
<label for="email">email</label>
<input type="text" id="email">
</div>
<div class="form-group">
<label for="msg">message</label>
<textarea id="msg"></textarea>
</div>
<button>send</button>
</form>
</div>
</div>
</div>
</section>
<!-- end Contact With Me -->
<script src="./js/script.js"></script>
</body>
</html>
CSS
<style>
/* import 구문은 항상 CSS 파일의 맨 윗줄에 작성 */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&family=Varela+Round&display=swap');
/* Header CSS */
.container{
width : 1140px;
margin : 0 auto;
}
/* 헤더 상단 고정 */
header{
position:fixed;
color: white;
top:0;
z-index: 1;
width: 100%;
padding: 1rem;
}
header .container{
display:flex;
justify-content: space-between; /* 양 끝에 배치 */
align-items: center;
width: 100%;
}
header nav ul{
display: flex; /* 메뉴 가로 배치 */
}
header nav ul li{
padding: 10px;
}
header button {
background: transparent;
border: 0;
cursor: pointer;
color: white;
}
header h1 button{ /* 로고 */
font-size: 2rem;
font-weight: bold;
color: white;
}
header nav ul li button{
font-size: 1.2rem;
}
/* Header END */
/* main CSS */
main{
width: 100%;
height: 100vh;
background: linear-gradient(rgba(0,0,0,0.8), rgba(0,0,0,0.8)), url('../images/me.jpg') center center;
background-size: cover;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
color: white;
}
main h4{
font-size: 2rem;
}
main h2{
font-size: 3.5rem;
margin: 2rem 0;
letter-spacing: 3px;
font-family: 'Varela Round', sans-serif;
}
main p{
max-width: 500px;
margin: 0 auto;
font-size: 1.25rem;
}
main button.download{
background-color: transparent;
color: white;
border: 3px solid white;
padding: 1rem 2rem;
border-radius: 30px;
margin-top: 3rem;
font-weight: bold;
cursor: pointer;
}
/* 아이콘 폰트, 마우스 버튼에 애니메이션 */
main button.mouse{
background-color: transparent;
border:none;
color:white;
font-size: 2rem;
position:absolute;
bottom: 1rem;
left: 50%;
transform: translateX(-50%);
animation: upDown 1s ease-in-out infinite;
}
@keyframes upDown{
0%{bottom: 1rem;}
50%{bottom: 1.5rem;}
100%{bottom: 1rem;}
}
main h2 span::after{
content:"";
height: 40px;
width: 3px;
background-color: white;
display:inline-block;
animation: blink .7s ease-in-out infinite;
}
@keyframes blink{
0%{opacity:1;}
100%{opacity:0;}
}
/* About me CSS */
/* 섹션 전체 */
section{
font-family: 'Poppins', sans-serif;
padding: 5rem 0;
}
section:nth-child(2n){
background-color: #f8f8f8;
}
/* 섹션 제목 */
section .title{
margin-bottom: 3rem;
}
section .title h4{
font-size: 1.35rem;
color: #ed4848;
position: relative;
}
section .title h2{
font-size: 3.5rem;
}
section .title p{
font-size: 1.15rem;
}
/* 섹션 내용 */
/* about-self 클래스 안에서 left, right 클래스 구성. width:50% */
section .about-self::after{
content:"";
clear:both;
display: block;
}
section .about-self .left{
width: 50%;
float: left;
}
section .about-self .left img{
max-width: 100%;
}
section .about-self .right{
width: 50%;
float: left;
padding: 0 2rem;
}
section .about-self .right h3{
font-size: 2.25rem;
margin-bottom: 1rem;
}
section .about-self .right h3 strong{
color: #ed4848;
}
section .about-self .right {
font-size: 1.15rem;
margin: 1rem 0;
}
section .about-self .right .social a{
font-size: 2.5rem;
margin-right: 0.2rem;
}
/* what i do CSS */
section .do-me::after{
content:"";
clear:both;
display: block;
}
/* 사각형 */
section .do-me .do-inner{
background-color:#fff;
width: 30%;
padding: 2rem;
float: left;
margin-right: 5%;
cursor:poingter;
}
section .do-me .do-inner:last-child{
margin-right: 0;
}
section .do-me .do-inner .icon i{
font-size: 2.5rem;
color: #ff6a6a;
}
section .do-me .do-inner .content h3{
font-size:2rem;
margin: 1rem 0;
}
section .do-me .do-inner:hover{
background-color: lightcoral;
color:white;
}
section .do-me .do-inner:hover i{
color:white;
}
/* background image 고정 */
.bg {
background: url('../images/background.jpg') center center;
background-size: cover;
background-attachment: fixed;
height: 650px;
}
/* Portfolio CSS */
section .portfolio::after{
content:"";
clear: both;
display: block;
}
/* 사각형 꾸미기 */
section.portfolio .portfolio-inner{
width: 30%;
margin-right:5%;
padding: 1rem 1rem 1.5rem 1rem;
float: left;
background-color: #f8f8f8;
border: 1px solid #ccc;
margin-bottom: 3rem;
}
section.portfolio .portfolio-inner:nth-child(3n){
margin-right:0;
}
section.portfolio .portfolio-inner img{
width: 100%;
display: block;
}
section.portfolio .portfolio-inner strong{
color:#ff6a6a;
margin: 0.5rem 0;
display: block;
}
section.portfolio .portfolio-inner h3{
font-size: 1.75rem;
}
/* contact with me CSS */
section.contact .contact-me::after{
content:"";
display:block;
clear:both;
}
/* left card */
section.contact .contact-me .left{
width: 30%;
float: left;
}
section.contact .contact-me .left .card{
border: 1px solid #ccc;
padding: 1rem;
display: flex;
align-items: center;
margin-bottom: 1.25rem;
}
section.contact .contact-me .left .ca rd.icon i{
font-size:2rem;
margin-right: 5px;
}
/* right card */
section.contact .contact-me .right{
margin-bottom : 2rem;
width: 65%;
float: left;
margin-left:5%;
}
section.contact .contact-me .right .form-group{
margin-bottom: 1.25rem;
}
section.contact .contact-me .right .form-group label{
display: block;
margin-bottom: 0.85rem;
}
section.contact .contact-me .right .form-group input{
padding: 0.625rem;
width: 65%;
outline: none;
border: 1px solid #ccc;
border-radius: 10px;
}
section.contact .contact-me .right form-group input:focus{
border: 1px solid #719ECE;
box-shadow: 0 0 10px #719ECE;
}
section.contact .contact-me .right .form-group textarea{
height: 300px;
width: 100%;
resize: none;
border: 1px solid #ccc;
border-radius: 10px;
}
section.contact .contact-me .right .form-group textarea:focus{
outline: none;
border: 1px solid #719ECE;
box-shadow: 0 0 10px #719ECE;
}
section.contact .contact-me .right button{
width: 100%;
padding: 1rem;
background-color: #f78b00;
border: none;
color:white;
}
</style>
Javascript
<script>
// 타이핑 효과
// span 요소 노드 가져오기
const spanE1 = document.querySelector("main h2 span");
const txtArr = ['web Publisher', 'Front-End Developer', 'UX Designer'];
let index = 0;
let currentTxt = txtArr[index].split(""); //currentTxt split 을 콘솔창에서 확인해보면 문장이 하나하나의 글자=인덱스로 나뉘어져있음
function writeTxt(){
spanE1.textContent += currentTxt.shift(); // 맨 앞의 인덱스 가져옴
if (currentTxt.length !== 0){
setTimeout(writeTxt, Math.floor(Math.random() * 100)); // 글자를 가지고 오는 시간을 랜덤하게 한다
} else {
currentTxt = spanE1.textContent.split("");
setTimeout(deleteTxt, 3000);
}
}
writeTxt();
// 삭제
function deleteTxt() {
currentTxt.pop();
spanE1.textContent = currentTxt.join("");
if (currentTxt.length !== 0){
setTimeout(deleteTxt, Math.floor(Math.random() * 100)); // 글자를 가지고 오는 시간을 랜덤하게 한다
} else {
index = (index + 1) % txtArr.length; // index: 0,1,2
currentTxt = txtArr[index].split("");
writeTxt();
}
}
const headerE1 =document.querySelector("header");
window.addEventListener('scroll', function(){
const browerScrollY = window.pageYOffset;
if (browerScrollY > 0){
headerE1.classList.add("active"); // 액티브라는 셋을 붙인다는 뜻
}else{
headerE1.classList.remove("active");
}
});
</script>
html css js의 쓰임새를 모두 생각하는게 어려웠던 것 같다
예제를 직접 써보니 모작하는 느낌처럼 구조짜는 감이 오는 것 같다
홈페이지를 빌드하기 전에 구성을 잘 짜야한다는 말이 이해가 된다.