2주차 실습. HTML, CSS, JavaScript

변현섭·2023년 10월 29일
0

데이터베이스설계

목록 보기
4/22
post-thumbnail

지난 포스팅에서 구축한 개발환경을 토대로, 이번에는 조금 더 다양한 기능을 가진 웹 페이지를 만들어 보도록 하겠습니다.

1. 자기소개 페이지 만들기

자기소개 페이지의 레이아웃은 header-footer, navigation bar, section을 사용하여 구성할 것이다.

1) HTML 파일

저번 포스팅에서 생성한 Database 폴더 하위로 week2 폴더를 추가한다. 그리고 VSCode를 실행하여 week2를 연다. 먼저 아래의 사진을 week2.png라는 이름으로 week2 디렉토리 하위에 추가한다.

이후 week1 디렉토리 하위로 assignment1.html 파일을 생성하고, 아래의 내용을 입력한다.

<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <title>HTML Practice</title>
</head>
<body>
    <header>
        <link rel="stylesheet" href="assignment1.css">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
        <div>
            <img src="./week2.png" alt="Selfie" id="fig">
        </div>
        <h1 style="text-align: left;">Hyun-seop Byun</h1>
        <p style="text-align: left;">Database</p>
    </header>
    <nav>
        <a href="#s1">[Personal information]</a>&nbsp;&nbsp;
        <a href="#s2">[Coursework]</a>&nbsp;&nbsp;
        <a href="#s3">[Courses]</a>&nbsp;&nbsp;
        <a href="#s4">[Introducing]</a>&nbsp;&nbsp;
    </nav>
    <section id="s1">
        <h2>Personal information</h2>
        <ul>
            <li>
                <span class="material-symbols-outlined">
                person
                </span>Hyun-seop Byun
            </li>
            <li>
                <span class="material-symbols-outlined">
                call
                </span>
                010-1234-5678
            </li>
            <li>
                <span class="material-symbols-outlined">
                    mail
                    </span>
                    gmlstjq123@naver.com
            </li>
            <li>
                <span class="material-symbols-outlined">
                    home
                    </span>
                    Incheon Michuhol-gu Inha-ro
            </li>
        </ul>
    </section>
    <section class="sc2" id="s2">
        <h2 class="c2">Coursework</h2>
        <ol>
            <li>        
                Operating System
            </li>
            <li>
                Computer Network
            </li>
            <li>Database Design</li>
            <li>Information protection</li>
        </ol>
    </section>
    <section class="sc3" id="s3">
        <h2 class="c3">Courses</h2>
        <ul>
            <li><a href="https://velog.io/@gmlstjq123">Blog</a></li>
            <li><a href="https://github.com/gmlstjq123">Github</a></li>
            <li><a href="https://polite-driver-4d9.notion.site/3ad1ff215345440791498cd5d39c5da4?pvs=4">Resume</a></li>
        </ul>
    </section>
    <section class="sc4" id="s4">
        <h2 class="c4">Introducing</h2>
        <p id="p1">
            <br>
            Hello, I'm Hyunseop. I'm in the department of Information and Communication Engineering.
            <br>
        </p>
    </section>
    <footer>
        &copy;Hyun-seop Byun<br>gmlstjq123@naver.com
    </footer>
</body>
</html>

① <!DOCTYPE html>

  • HTML5 문서 형식을 사용할 것을 선언한다.

② <head>

  • HTML 문서의 머리말 부분으로써, 문서의 메타데이터와 연결된 style sheet 및 script 파일이 들어간다.
  • <meta charset="utf-8">: UTF-8 문자 인코딩을 사용할 것을 선언한다.
  • <title>HTML Practice</title>: 브라우저 탭에 표시될 웹 페이지의 제목을 정의한다.

③ <body>

  • HTML 문서의 본문으로써, 웹 페이지의 내용이 들어간다.

④ <header>

  • header-footer 레이아웃의 헤더 부분이다.
  • <link rel="stylesheet" href="assignment1.css">: 외부 CSS 스타일 시트 파일인 "assignment1.css"를 연결한다.
  • <link rel="stylesheet" href="https://...">: Google Fonts에서 가져온 외부 스타일 시트를 연결한다.

⑤ <div>

  • 관련된 요소끼리 그룹화하고 다른 영역과의 분리를 목적으로 사용되는 공간 분할 태그이다.
  • 여기서는 공간 분할의 의미보다는 CSS의 선택자로 지정하기 위해 사용되었다.

⑥ <img src="./week2.png" alt="Selfie" id="fig">

  • "week2.png" 이미지를 나타낸다.
  • 이미지 로드에 실패한 경우, 대체 텍스트인 "Selfie"를 화면에 띄운다.
  • ID를 fig로 지정한다.

⑦ <h1 style="text-align: left;">Hyun-seop Byun

  • hn 태그는 n의 값이 작을수록 text size가 크고 중요도가 높다.
  • 태그 안에 style 속성을 추가하는 방식으로 인라인 스타일을 사용할 수도 있다. 인라인 속성들은 ;로 구분된다.
  • 참고로 text-align은 텍스트 정렬을 위해 사용되는 속성이다.

⑧ <p style="text-align: left;">Database

  • body에 문단을 작성하기 위해 주로 사용되는 태그이다.

⑨ <nav>

  • 웹 페이지의 네비게이션 바로써, 다른 섹션으로 이동하는 링크가 포함된다.
  • <a href="#s1">[Personal information]
    • href 속성에 #s1을 사용함으로써, Personal information 섹션에 링크된다.
    • 참고로   는 Non-breaking Space의 줄임말로, 띄어쓰기를 하되, 줄바꿈을 하지 않는다는 의미이다. (space bar를 사용할 경우, 필요요에 따라 자동 줄바꿈 된다.)

⑩ <ul> & <li>

  • <ul>은 Unordered List로, 순서가 없는 목록을 의미한다.
  • <ul> 요소 안에 포함될 아이템을 <li> 태그로 추가할 수 있다.

⑪ <footer>

  • header-footer 레이아웃의 푸터 부분이다.

2) CSS 파일

HTML 파일에 CSS 서식을 적용하는 방법은 총 3가지이다.

  • 내부 스타일 시트 방식: <head> 태그 안에 <style> 태그를 사용
  • 외부 스타일 시트 방식: 별도의 CSS 파일을 생성하여, HTML과 링크
  • 인라인 스타일 방식

여기서는 외부 스타일 시트 방식을 사용할 것이므로, week1 디렉토리 하위로 assignment1.css 파일을 생성하고, 아래의 내용을 입력한다.

body {
    margin: 0px;
    padding: 0px;
}

header {
    width: 100%;
    background-color: #005766;
    height: 200px;
}

header>div {
    float: left;
}

header h1,
header p {
    color: white;
    text-align: center;
    margin: 30px;
}

header img {
    height: 150px;
    padding: 20px;
}

nav {
    clear: both;
    background-color: #3db7cc;
    height: 35px;
}

nav a {
    width: 170px;
    height: 35px;
    padding: 5px;
    display: inline-block;
    text-decoration: none;
    text-align: center;
}

section {
    margin: 10px;
    padding: 10px;
    width: 45%;
    height: 200px;
    float: left;
    border: 1px solid #3db7cc;
    box-sizing: border-box;
}

section p,
section ul,
section ol {
    padding-left: 50px;
}

h2 {
    margin: 5px;
    padding: 10px;
    background-color: #005766;
    color: rgb(255, 255, 255);
}

section a {
    width: 80%;
    height: 15px;
    padding: 5px;
}

footer {
    clear: both;
    height: 50px;
    background-color: #eaeaea;
    color: #5d5d5d;
    padding: 20px;
    font-size: 12px;
}

① body

  • 페이지 전체에 적용되는 스타일 규칙을 정의한다.

② header

  • 페이지의 헤더 부분에 적용되는 스타일 규칙을 정의한다.
  • width: 100%;: 헤더의 폭을 페이지 너비와 동일하게 설정한다.

③ header > div

  • <header> 내부의 <div> 요소에 적용되는 스타일 규칙을 정의한다.
  • >는 부모 요소의 하위에 있는 자식 요소에 스타일을 적용해야 할 때 사용하는 선택자이다.
  • float: left;: <div>를 왼쪽으로 띄워서 배치한 후 다음에 오는 텍스트나 이미지 등의 요소를 옆에 자연스럽게 배치한다.

④ header h1, header p

  • <header>에 있는 <h1>과 <p> 요소를 스타일링합니다.
  • 공백을 구분자로 단순 나열하는 방식은 하위에 있는 요소를 선택할 때 사용하는 선택자이다.
  • 여기서는 >를 사용하는 방식과 동일하게 동작한다.

⑤ nav

  • 네비게이션 바에 적용되는 스타일 규칙을 정의한다.
  • clear: both;
    • float 속성을 해제하기 위해 사용한다.
    • clear: left;를 사용해도 된다.

⑥ nav a

  • display: inline-block;: 링크를 인라인 블록으로 표시하여 가로로 배치한다.
  • text-decoration: none;: 밑줄을 제거하여 하이퍼링크 모양을 없앤다.

    ※ 블록 VS 인라인 VS 인라인 블록
    hn, p, div와 같이 요소의 너비가 항상 한 줄을 다 차지하는 것을 블록 성격을 갖는다고 말하고, a, span, strong 태그와 같이 요소의 너비가 컨텐츠 크기만큼만 차지하는 것은 인라인 성격을 갖는다고 한다. 블록 성격에는 width, height, margin, padding을 모두 적용 가능하지만, 인라인 성격에는 horizontal padding과 horizontal margin만 적용할 수 있다.
    인라인 블록은 인라인과 블록의 성격이 혼합된 형태이다. 요소의 너비가 컨텐츠의 크기만큼만 차지하긴 하나 width, height, margin, padding을 적용할 수 있다.

⑦ section

  • box-sizing: border-box;
    • 요소의 크기를 테두리(border)를 포함한 상자 전체의 크기로 계산한다.
    • 이 속성을 설정하지 않을 경우, content, margin, border, padding을 모두 합친 값으로 계산한다.

각각의 파일을 ctrl + s를 눌러 저장한다. assignment1.html 파일을 열어둔 상태에서 ctrl + shift + p를 누르고 Live Server: Open with Live Server를 클릭한다.

위 과정이 정상적으로 완료되었다면, 아래와 같은 웹 페이지가 나타날 것이다.

2. 다양한 입력을 처리할 수 있는 폼 만들기

이번에는 HTML로 사용자 입력 폼을 만드는 방법에 대해 실습해보기로 하자.

1) 텍스트, 비밀번호, 라디오버튼, 체크 박스 타입의 입력

week1 디렉토리 하위로, assignment2.html을 생성하고 아래의 내용을 입력한다.

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>HTML Practice</title>
</head>

<body>
    <form method="get" action="#" accept-charset="utf-8" name="person_info">
        <fieldset style="width: 150">
            <legend>Personal Information</legend>
            Name: <input type="text" name="name" required /><br /><br />
            Student Number:
            <input type="text" name="security_number" pattern="\d{8}"
                title="Please enter your 8-digit Student number!" /><br /><br />
            ID: <input type="text" name="id" /><br /><br />
            Passwords: <input type="password" name="password" /><br /><br />
            Gender: M<input type="radio" name="gender" />
                    W<input type="radio" name="gender" /><br /><br />
            Interests: Economy<input type="checkbox" name="checkbox1" />
            Sports<input type="checkbox" name="checkbox2" />
            IT<input type="checkbox" name="checkbox3" /><br /><br />

            <input type="submit" value="submit" /><br /><br />
            <input type="reset" value="reset" /><br /><br />
        </fieldset>
    </form>
</body>

</html>

① <form>

  • method="get": 폼 전송에 사용할 HTTP 메서드를 지정한다.
  • action="#": 폼 데이터를 전송할 서버 스크립트나 URL을 지정한다. 여기서는 현재 페이지에 데이터를 전송하고 있다.
  • name="person_info": 폼의 이름을 "person_info"로 지정합니다.

② <fieldset>

  • 폼 태그 내의 요소를 그룹화하고 박스모양의 테두리를 적용한다.
  • <legend>: fieldset으로 그룹화한 요소의 이름을 붙이기 위해 사용한다.

③ <input>

  • type
    • 상황에 따라 text, password, radio, checkbox를 사용할 수 있다.
    • type이 submit이거나 reset일 경우, 제출 또는 초기화 버튼이 생기며, value 속성을 이용해 버튼에 표시할 텍스트를 지정할 수 있다.
  • name: 이 필드의 이름을 지정한다. 이 이름은 폼이 제출될 때 서버에게 전달되는 이름이다.
  • required: 필수 입력 값임을 나타낸다.
  • \d{8}: 8자리 숫자만 유효한 입력으로 받아들인다.
  • title: 입력 필드에 커서를 가져다 댈 때 나타나는 툴팁 메시지를 정의한다.

완성된 모습은 아래와 같다.

2) 드롭다운 메뉴(스크롤, 콤보 박스) 타입의 입력

이번에는 assignment3.html에 아래의 내용을 입력해보자.

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>HTML Practice</title>
</head>

<body>
    <form method="get" action="#" accept-charset="utf-8" name="person_info">
        <fieldset style="width: 250">
            <legend>personal information</legend>
            Select region (with size, multiple attributes)<br />
            <select name="region-1" size="5" ltiple>
                <option value="seongnam-si">seongnam-si</option>
                <option value="suwon-si">suwon-si</option>
                <option value="yongin-si">yongin-si</option>
                <option value="anyang-si">anyang-si</option>
                <option value="gwacheon-si">gwacheon-si</option>
                <option value="hanam-si">hanam-si</option>
            </select>
            <br /><br />
            Select region (with optgroup tag)<br />
            <select name="region-1">
                <optgroup label="Seoul">
                    <option value="songpa-gu">songpa-gu</option>
                    <option value="gangnam-gu">gangnam-gu</option>
                    <option value="seocho-gu">seocho-gu</option>
                    <option value="junggu-gu">junggu-gu</option>
                </optgroup>
                <optgroup label="Gyeonggi-do">
                    <option value="seongnam-si">seongnam-si</option>
                    <option value="suwon-si">suwon-si</option>
                    <option value="yongin-si">yongin-si</option>
                    <option value="anyang-si">anyang-si</option>
                </optgroup>
            </select>
            <br /><br />
            <input type="submit" value="submit" /><br /><br />
            <input type="reset" value="reset" /><br /><br />
        </fieldset>
    </form>
</body>

</html>

① <select name="region-1" size="5" multiple>

  • name: 드롭다운 목록의 이름을 지정한다. 이 이름은 폼이 제출될 때 서버에서 사용할 이름이다.
  • size: 드롭다운 메뉴에 몇 개의 항목이 보이는지 설정한다.
  • multiple: 여러 항목을 선택할 수 있게 한다. ctrl을 눌러 복수 선택이 가능하다. size 또는 multiple을 지정하면 스크롤이 생긴다.

② <optgroup>

  • 드롭다운 목록 내에서 관련된 항목들을 그룹화한다.
  • <option>: 요소가 드롭다운 목록의 선택 항목으로 나타난다.

완성된 모습은 아래와 같다.

3. JavaScript 사용하기

이제부터 본격적으로 JavaScript를 연결하여 사용해보도록 하겠다.

1) HTML 파일

assignment4.html 파일에 아래의 내용을 입력한다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>HTML Practice</title>
</head>
<body>
    <h1>Create An Account</h1>
    <form id="user">
        <div>
            <label for="firstname">First name</label>
            <input id="firstname" type="text" required placeholder="First name">
        </div>
        <div>
            <label for="lastname">Last name</label>
            <input id="lastname" type="text" placeholder="Last name">
        </div>
        <div>
            <label for="mail">Email</label>
            <input id="mail" type="email" placeholder="Email">
        </div>
        <div>
            <label for="userid">Username</label>
            <input id="userid" type="text" placeholder="Username">
        </div>
        <div>
            <label for="pw">Password</label>
            <input id="pw" type="password" minlength="10" placeholder="Password">
        </div>
        <div>
            <label for="date">Birth date</label>
            <input id="date" type="date" placeholder="Username">
        </div>
        <div>
            <label for="slide">How happy are you?</label>
            <input id="slide" type="range" list="tickmarks">
            <datalist id="tickmarks">
                <option value="0"></option>
                <option value="10"></option>
                <option value="20"></option>
                <option value="30"></option>
                <option value="40"></option>
                <option value="50"></option>
                <option value="60"></option>
                <option value="70"></option>
                <option value="80"></option>
                <option value="90"></option>
                <option value="100"></option>
            </datalist>
        </div>
        <div>
            <label for="color">What is your fav.color?</label>
            <input id="color" type="color">
        </div>
        <input type="submit" value="Create Account">
    </form>
    <div id="form-result">
        <span></span>
    </div>
    <script type="text/javascript" src="assignment4.js"></script>
</body>
</html>

  • type으로 range를 지정하면, slide 입력 필드를 사용할 수 있다.
  • 이 입력 요소가 사용할 datalist의 id를 지정한다.
  • 입력 폼의 결과를 나타내기 위한 공간이다.

2) JavaScript 파일

assignment4.js 파일에 아래의 내용을 입력한다.

const firstName = document.getElementById("firstname");
const lastName = document.getElementById("lastname");
const email = document.getElementById("mail");
const userid = document.getElementById("userid");
const printForm = document.getElementById("user");
const display = document.getElementById("form-result");
  
const handlePrint = (e) => {
    e.preventDefault(); // Prevents the window from moving
    const fn = firstName.value;
    const ln = lastName.value;
    const em = email.value;
    const id = userid.value;
    const displaySpan = display.querySelector("span"); // Select the span tag inside the tag with id form-result
    displaySpan.innerHTML = `First Name is: ${fn}<br>
    Last Name is: ${ln}<br>
    E-mail is: ${em}<br>
    ID is: ${id}`;
};
  
printForm.addEventListener("submit", handlePrint);

① const handlePrint = (e)

  • 이벤트 핸들러 함수를 정의한다.
  • handlePrint 함수는 이벤트 객체 e를 매개변수로 받으며, 폼이 제출될 때 실행된다.

② e.preventDefault();

  • 이벤트의 기본 동작을 막는다.
  • 여기서는 폼 제출 시 페이지의 새로고침을 막아 원래 페이지에서 결과를 표시하기 위해 사용한다.

③ displaySpan.innerHTML

  • innerHTML : span 태그를 선택하고, 그 안에 내용을 적기 위해 사용한다.

완성된 모습은 아래와 같다.

4. 숫자 맞추기 게임

assignment5.html에 아래의 내용을 입력한다.

1) HTML 파일

<!DOCTYPE html>
<html>

<head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
</head>

<body>
    <h1>Random Number Game</h1>
    <div id="js-title">
        <h3 class="js-title">Generate a number between 0 and <span>200</span></h3>
        <datalist id="number">
            <option value="50"></option>
            <option value="100"></option>
            <option value="150"></option>
            <option value="200"></option>
        </datalist>
        <input list="number" id="js-range" type="range" min="5" max="200" value="5" step="5" />
    </div>
    <form id="js-guess">
        <label for="num">Guess the number:</label>
        <input id="num" type="number" max="200" min="0" />
        <button>Play!</button>
    </form>
    <div id="js-result">
        <span></span>
    </div>

    <script type="text/javascript" src="assignment5.js"></script>

</body>

</html>

2) JavaScript 파일

assignment5.js 파일에 아래의 내용을 입력한다. 자세한 설명은 주석으로 대체하기로 한다.

const dataList = document.getElementById("number"); // 슬라이드
const rangeInput = document.getElementById('js-range'); // 랜덤 숫자의 범위
const guessForm = document.getElementById('js-guess'); // 추측 숫자를 받는 폼
const resultSpan = document.querySelector('#js-result span'); // 승패 결과 표기
const selectedValueSpan = document.querySelector('#js-title .js-title span'); // 최대 범위 표기

// 랜덤 숫자가 변경되는 이벤트에 대한 리스너
rangeInput.addEventListener('input', () => {
    // input 태그의 값을 최대 범위 표기에 넘겨줌
    const selectedValue = rangeInput.value;
    selectedValueSpan.textContent = selectedValue;
});


function playGame() {
    const selectedNumber = parseInt(rangeInput.value); // 최대 범위를 정수로 형변환
    const randomNumber = getRandomNumber(selectedNumber); // 0 ~ 최대범위 랜덤 수 생성

    // 사용자 입력 숫자 가져오기
    const guessedNumber = parseInt(document.getElementById('num').value);

    if (guessedNumber === randomNumber) {
        // 리터럴을 사용하려면 따옴표가 아닌 백틱을 사용
        resultSpan.innerHTML = `You choose: ${guessedNumber}, the machine choose: ${randomNumber}.<br><b>You win!</b>`;
    } else {
        resultSpan.innerHTML = `You choose: ${guessedNumber}, the machine choose: ${randomNumber}.<br><b>You lose!</b>`;
    }
}

// Play를 클릭
guessForm.addEventListener('submit', (event) => {
    event.preventDefault(); // 폼 제출 기본 동작 막기
    playGame(); // 게임 실행
});

// 최대 범위를 입력받아 랜덤 숫자 생성
function getRandomNumber(selectedValue) {
    const randomNumber = Math.floor(Math.random() * (selectedValue + 1)); // max 범위 + 1 미만의 자연수 생성
    return randomNumber;
}

완성된 모습은 아래와 같다.

profile
Java Spring, Android Kotlin, Node.js, ML/DL 개발을 공부하는 인하대학교 정보통신공학과 학생입니다.

0개의 댓글