[WEB FRONT] 시험 - 23.09.21

유진·2023년 9월 21일
0

9/21(목) UI 구현 : (HTML + CSS) + JS

Portfolio-test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Portfolio-test</title>

    <link rel="stylesheet" href="Portfolio-test.css">

    <script src="https://kit.fontawesome.com/f821b57119.js" crossorigin="anonymous"></script>
</head>
<body>
    <section id="big-section">
        <!-- header -->
        <header>
            <!-- nav -->
            <nav>
                <div>
                    <a href="#"><button type="button">Home</button></a>
                    <a href="#about"><button type="button">About</button></a>
                    <a href="#projects"><button type="button">Projects</button></a>
                    <a href="#contact"><button type="button">Contact</button></a>
                </div>
                <div>
                    <button class="fa-solid fa-palette" id="color-mode"></button>
                    <a href="https://github.com/yujinjjang2" target="_blank"><button type="button" class="fa-brands fa-github"></button></a>
                    <a href="https://velog.io/@o3odw98" target="_blank"><button type="button" class="fa-solid fa-pen-to-square"></button></a>
                </div>
            </nav>

            <div>
                <div>
                    <img src="images/profile.png" id="profile">
                </div>
                <div>
                    <div>
                        Hello <br>
                        This is Lee Yu-jin , <br>
                        a prospective developer ! <br><br>

                        A Multi talented software developer
                    </div>
                    <div>
                        <a href="#" target="_blank"><button type="button" id="resume-btn">Download My Resume</button></a>
                    </div>
                </div>
            </div>
        </header>

        <!-- main -->
        <main>
            <!-- About -->
            <section class="about" id="about">
                <div>
                    About
                </div>
                <div>
                    안녕하세요 , 예비 개발자를 꿈꾸는 이유진입니다 !
                </div>
                <div>
                    NAME : 이유진 <br>
                    BIRTHDAY : 1998-09-03 <br>
                    ADDRESS : 서울시 성북구 <br>
                    PHONE : 010-2485-4855 <br>
                    EMAIL : o3odw98@gmail.com <br><br>

                    “ No pain, No gain 고통없이 얻는 것은 없다. ” <br>
                    제가 마음 속에 항상 새기는 문장입니다. <br>
                    힘든 순간이 찾아와도 끈기를 가지고 맡은 일을 마무리하고자 합니다. <br>
                    JAVA, JS, CSS, HTML 등 다양한 언어를 공부하며 개발에 대한 관심 및 분야를 넓히고 있습니다.
                </div>
                <div>
                   <div></div> 
                   <div>
                        <a href="#" target="_blank"><button type="button" id="hire-btn">Hire Me</button></a>
                   </div> 
                   <div>
                        <a href="#"><button type="button" class="fa-solid fa-angles-up" id="up-btn"></button></a>
                   </div> 
                </div>
            </section>

            <!-- Projects -->
            <section class="projects" id="projects">
                <div>
                    Projects
                </div>
                <div class="youtube">
                    <div>
                        <img src="images/youtube_img.png" id="youtube-img">
                    </div>
                    <div>
                        <div>
                            Youtube Clone
                        </div>
                        <div>
                            유튜브 클론은 제 첫번째 프로젝트 결과물입니다.
                        </div>
                        <div>
                            <a href="https://github.com/yujinjjang2/CLONE_YOUTUBE_mob" target="_blank"><u>See More...</u></a>
                        </div>
                    </div>
                </div>

                <div class="naver">
                    <div>
                        <div>
                            Naver Clone
                        </div>
                        <div>
                            네이버 클론은 제 두번째 프로젝트 결과물입니다.
                        </div>
                        <div>
                            <a href="https://github.com/yujinjjang2/CLONE_NAVER" target="_blank"><u>See More...</u></a>
                        </div>
                    </div>
                    <div>
                        <img src="images/naver_img.png" id="naver-img">
                    </div>
                </div>
                <div>
                    <div></div>
                    <div>
                        <a href="#"><u>View All Projects...</u></a>
                    </div>
                    <div>
                        <a href="#"><button type="button" class="fa-solid fa-angles-up" id="up-btn"></button></a>
                    </div>
                </div>
            </section>
        </main>

        <!-- footer -->
        <footer id="contact">
            <div>
                Contact Me
            </div>
            <div>
                채용을 원하시면 바로 연락드리겠습니다.
            </div>
            <div>
                <div></div>
                <div>
                    <form action="#" target="_blank" id="form">
                        <input type="text" id="form-name" name="name" placeholder="Name(한글 2자이상 5자이하)" autocomplete="off">
                        <span id="span-name"></span>
                        <input type="text" id="form-email" name="email" placeholder="Email" autocomplete="off">
                        <span id="span-email"></span>
                        <input type="text" id="form-body" name="body" placeholder="Body" autocomplete="off">

                        <button type="submit" id="send-btn">Send</button>
                    </form>
                </div>
                <div>
                    <a href="#"><button type="button" class="fa-solid fa-angles-up" id="up-btn"></button></a>
                </div>
            </div>
        </footer>
    </section>

    <script src="Portfolio-test.js"></script>
</body>
</html>

Portfolio-test.css

@font-face {
    font-family: 'omyu_pretty';
    src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2304-01@1.0/omyu_pretty.woff2') format('woff2');
    font-weight: normal;
    font-style: normal;
}

* {
    box-sizing: border;
    font-family: 'omyu_pretty';
}

/* div, section {
    border: 1px solid black;
} */

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

    display: flex;
    justify-content: center;
}

body > section {
    width: 1440px;
    height: 350vh;

    display: flex;
    flex-direction: column;

    background-color: #FAF6F6;
}

header, footer {
    flex-basis: 20%;
}

main {
    flex-basis: 60%;
}



/* header */
header {
    display: flex;
    flex-direction: column;

    background-image: url("images/background.png");
}

nav {
    flex-basis: 20%;

    display: flex;
}

header > div {
    flex-basis: 80%;
}

nav > div:nth-child(1) {
    flex-basis: 70%;

    display: flex;
    justify-content: space-around;
    align-items: center;
}

nav > div:nth-child(2) {
    flex-basis: 30%;

    display: flex;
    align-items: center;
    justify-content: flex-end;
}

nav > div:nth-child(1) > a > button {
    border: none;
    background-color: transparent;
    font-size: 30px;
}

nav > div:nth-child(1) > a > button:hover {
    border: 1px solid #dadada;
    border-radius: 10px;
    background-color: #dadada;
    font-size: 35px;
    font-weight: bold;
    width: 200px;
    height: 50px;
}

nav > div:nth-child(2) > button {
    border: none;
    background-color: transparent;
    font-size: 50px;
    margin: 20px;
}

nav > div:nth-child(2) > button:hover {
    border: 1px solid #ddd;
    border-radius: 50px;
    background-color: #ddd;
    font-size: 60px;
    width: 80px;
    height: 80px;
}

nav > div:nth-child(2) > a > button {
    border: none;
    background-color: transparent;
    font-size: 50px;
    margin: 20px;
}

nav > div:nth-child(2) > a > button:hover {
    border: 1px solid #ddd;
    border-radius: 50px;
    background-color: #ddd;
    font-size: 60px;
    width: 80px;
    height: 80px;
}

header > div {
    display: flex;
}

header > div > div {
    flex-basis: 50%;
}

header > div > div:nth-child(1) {
    display: flex;
    justify-content: center;
}

header > div > div:nth-child(2) {
    display: flex;
    flex-direction: column;
}

header > div > div:nth-child(2) > div:nth-child(1) {
    flex-basis: 60%;

    display: flex;
    align-items: center;
    font-size: 30px;
    font-weight: bold;
    font-style: italic;
}

header > div > div:nth-child(2) > div:nth-child(2) {
    flex-basis: 40%;

    display: flex;
    justify-content: flex-end;
}

#resume-btn {
    border: none;
    background-color: black;
    color: white;
    border-radius: 10px;
    width: 200px;
    height: 50px;
    font-size: 20px;
    margin: 20px;
}

#resume-btn:hover {
    background-color: #ddd;
    color: black;
    font-weight: bold;
}


/* main */
main {
    display: flex;
    flex-direction: column;
}

.about {
    flex-basis: 40%;

    display: flex;
    flex-direction: column;
}

.projects {
    flex-basis: 60%;
}

.about > div:nth-child(1) {
    flex-basis: 20%;

    display: flex;
    justify-content: center;
    align-items: center;

    font-size: 50px;
    font-weight: bold;
    font-style: italic;
    text-shadow: 5px 5px #ddd;
}

.about > div:nth-child(2) {
    flex-basis: 10%;

    display: flex;
    justify-content: center;
    align-items: center;

    font-size: 30px;
    font-weight: bold;
}

.about > div:nth-child(3) {
    flex-basis: 50%;

    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;

    font-size: 22px;
}

.about > div:nth-child(4) {
    flex-basis: 20%;

    display: flex;
}

.about > div:nth-child(4) > div:nth-child(1),
.about > div:nth-child(4) > div:nth-child(3) {
    flex-basis: 20%;
}

.about > div:nth-child(4) > div:nth-child(2) {
    flex-basis: 60%;

    display: flex;
    justify-content: center;
    align-items: center;
}

#hire-btn {
    border: none;
    border-radius: 10px;
    background-color: black;
    color: white;
    width: 200px;
    height: 50px;
    font-size: 25px;
}

#hire-btn:hover {
    background-color: #ddd;
    color: black;
    font-weight: bold;
    font-size: 30px;
}

.about > div:nth-child(4) > div:nth-child(3) {
    flex-basis: 20%;

    display: flex;
    justify-content: center;
    align-items: center;
}

#up-btn {
    border: none;
    background-color: transparent;
    color: gray;
    font-size: 100px;
}

#up-btn:hover {
    color: rgb(73, 73, 73);
}


.projects {
    display: flex;
    flex-direction: column;
}

.projects > div:nth-child(1) {
    flex-basis: 15%;

    display: flex;
    justify-content: center;
    align-items: center;

    font-size: 50px;
    font-weight: bold;
    font-style: italic;
    text-shadow: 5px 5px #ddd;
}

.projects > div:nth-child(2),
.projects > div:nth-child(3) {
    flex-basis: calc(70%/2);
}

.projects > div:nth-child(4) {
    flex-basis: 15%;
}

.youtube {
    display: flex;
}

.youtube > div {
    flex-basis: 50%;
}

.youtube > div:nth-child(1) {
    display: flex;
    align-items: center;
    margin: 20px;
}

#youtube-img {
    width: 100%;
    height: 350px;
    border: 2px solid #ddd;
    border-radius: 20px;
}

.youtube > div:nth-child(2) {
    display: flex;
    flex-direction: column;
}

.youtube > div:nth-child(2) > div:nth-child(1) {
    flex-basis: 50%;

    display: flex;
    align-items: center;

    font-size: 40px;
    font-weight: bold;
    font-style: italic;
    text-shadow: 2px 2px #ddd;
}

.youtube > div:nth-child(2) > div:nth-child(2) {
    flex-basis: 30%;

    font-size: 25px;
}

.youtube > div:nth-child(2) > div:nth-child(3) {
    flex-basis: 20%;
}

.youtube > div:nth-child(2) > div:nth-child(3) > a > u {
    color: black;
    font-size: 25px;
}

.youtube > div:nth-child(2) > div:nth-child(3) > a > u:hover {
    border: none;
    border-radius: 10px;
    background-color: #ddd;
    color: black;
}

.naver {
    display: flex;
}

.naver > div {
    flex-basis: 50%;
}

.naver > div:nth-child(1) {
    display: flex;
    flex-direction: column;
    margin: 10px;
}

.naver > div:nth-child(1) > div:nth-child(1) {
    flex-basis: 50%;

    display: flex;
    align-items: center;

    font-size: 40px;
    font-weight: bold;
    font-style: italic;
    text-shadow: 2px 2px #ddd;
}

.naver > div:nth-child(1) > div:nth-child(2) {
    flex-basis: 30%;

    font-size: 25px;
}

.naver > div:nth-child(2) {
    display: flex;
    align-items: center;
    margin: 20px;
}

.naver > div:nth-child(1) > div:nth-child(3) > a > u {
    color: black;
    font-size: 25px;
}

.naver > div:nth-child(1) > div:nth-child(3) > a > u:hover {
    border: none;
    border-radius: 10px;
    background-color: #ddd;
    color: black;
}

#naver-img {
    width: 100%;
    height: 400px;
    border: 2px solid #ddd;
    border-radius: 20px;
}

.projects > div:nth-child(4) {
    display: flex;
}

.projects > div:nth-child(4) > div:nth-child(1),
.projects > div:nth-child(4) > div:nth-child(3) {
    flex-basis: 20%;

    display: flex;
    justify-content: center;
    align-items: center;
}

.projects > div:nth-child(4) > div:nth-child(2) {
    flex-basis: 60%;

    display: flex;
    justify-content: center;
    align-items: center;
}

.projects > div:nth-child(4) > div:nth-child(2) > a > u {
    color: black;
    font-size: 30px;
}

.projects > div:nth-child(4) > div:nth-child(2) > a > u:hover {
    color: grey;
}


/* footer */
footer {
    display: flex;
    flex-direction: column;
}

footer > div:nth-child(1) {
    flex-basis: 20%;

    display: flex;
    justify-content: center;
    align-items: center;

    font-size: 50px;
    font-weight: bold;
    font-style: italic;
    text-shadow: 5px 5px #ddd;
}

footer > div:nth-child(2) {
    flex-basis: 10%;

    display: flex;
    justify-content: center;
    align-items: center;

    font-size: 30px;
}

footer > div:nth-child(3) {
    flex-basis: 70%;

    display: flex;
}

footer > div:nth-child(3) > div:nth-child(1),
footer > div:nth-child(3) > div:nth-child(3) {
    flex-basis: 20%;

    display: flex;
    justify-content: center;
    align-items: end;
}

footer > div:nth-child(3) > div:nth-child(2) {
    flex-basis: 60%;

    display: flex;
    justify-content: center;
    align-items: center;
}

#form {
    display: flex;
    flex-direction: column;
}

#form > input {
    width: 600px;
    height: 40px;
    border: 2px solid #ddd;
    border-radius: 20px;
    margin: 10px 0px;
    padding-left: 20px;
}

#form > #form-body {
    height: 200px;
}

#send-btn {
    width: 630px;
    height: 40px;
    border: none;
    border-radius: 10px;
    background-color: black;
    color: white;
    font-size: 20px;
}

#send-btn:hover {
    background-color: #ddd;
    color: black;
    font-weight: bold;
}



/* 추가 속성 */
button {
    cursor: pointer;
}

Portfolio-test.js

// 변수 선언
let nameFlag = false;
let mailFlag = false;

// Contact Me : Name
document.getElementById("form-name").addEventListener("keyup", function() {

    // span-name 객체 가져오기
    const spanName = document.getElementById("span-name");

    // 한글 2자이상 5자이하 정규표현식
    const regExp = /^[가-힣]{2,5}$/;

    // 값이 없을 경우
    if(this.value == 0) {
        spanName.innerText = "";
        return;
    }

    // 유효성 검사
    if(regExp.test(this.value)) {
        // 값이 유효할 경우
        spanName.innerText = "유효한 형식의 이름입니다.";
        spanName.style.color = "green";
        spanName.style.fontWeight = "bold";
        nameFlag = true;
    } else {
        // 값이 유효하지 않을 경우
        spanName.innerText = "유효하지 않은 형식의 이름입니다.";
        spanName.style.color = "red";
        spanName.style.fontWeight = "bold";
        nameFlag = false;
    }
});

// Contact Me : Email
document.getElementById("form-email").addEventListener("keyup", function() {

    // span-email 객체 가져오기
    const spanEmail = document.getElementById("span-email");

    // 이메일 정규표현식
    const regExp = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i;

    // 값이 없을 경우
    if(this.value == 0) {
        spanEmail.innerText = "";
        return;
    }

    // 유효성 검사
    if(regExp.test(this.value)) {
        // 값이 유효할 경우
        spanEmail.innerText = "유효한 형식의 이메일입니다.";
        spanEmail.style.color = "green";
        spanEmail.style.fontWeight = "bold";
        mailFlag = true;
    } else {
        // 값이 유효하지 않을 경우
        spanEmail.innerText = "유효하지 않은 형식의 이메일입니다.";
        spanEmail.style.color = "red";
        spanEmail.style.fontWeight = "bold";
        mailFlag = false;
    }
});

// Contact Me : Send Button
document.getElementById("send-btn").addEventListener("click", function(event){

    // form-name, form-email 객체 가져오기
    const formName = document.getElementById("form-name");
    const formEmail = document.getElementById("form-email");

    // 이름 NULL 체크 및 유효성 확인
    if(isNull(formName.value)) {
        alert("이름을 입력해주세요.");
        event.preventDefault();
        return;
    } else {
        if(nameFlag == false) {
            alert("유효한 형식의 이름을 입력해주세요.");
            event.preventDefault();
            return;
        }
    }

    // 이메일 NULL 체크 및 유효성 확인
    if(isNull(formEmail.value)) {
        alert("이메일을 입력해주세요.");
        event.preventDefault();
        return;
    } else {
        if(mailFlag == false) {
            alert("유효한 형식의 이메일을 입력해주세요.");
            event.preventDefault();
            return;
        }
    }
});

// NULL 체크 함수
function isNull(str) {
    if(str == "null" || str == "" || str == undefined) {
        return true;
    } else {
        return false;
    }
}

// 다크모드 변경
document.getElementById("color-mode").addEventListener("click", function() {

    // big-section 객체 가져오기
    const bigSection = document.getElementById("big-section");

    // big-section 배경색
    const bgColor = bigSection.style.backgroundColor;

    // 다크모드 변경
    if(bgColor == "white" || isNull(bgColor)) {
        bigSection.style.backgroundColor = "black";
        bigSection.style.color = "yellow";
    } else {
        bigSection.style.backgroundColor = "white";
        bigSection.style.color = "black";
    }
});

[ 구현 화면 ]

0개의 댓글