HTML과 CSS

6. 여러가지 기능 구현하기 - 2

char1ey 2022. 10. 31. 16:31
목차
1. 로그인 Form(layer pop_up)

  1.1. 기본 HTMl 구성 및 CSS 적용
    1.1.1. HTML 구성
    1.1.2. CSS 적용
  1.2. box-shadow 속성
  1.3. 로그인 폼 기능 구현하기
    1.3.1. <form>과 <input>, <button>의 속성 및 상호관계
  1.4. 로그인 폼 마무리

2. 메뉴폼

  2.1. HTML 구성
  2.2. CSS 적용
    2.2.1. after와 before
3. media query 문법 (반응형 웹)

 


1. 로그인 Form (layer pop_up)

 

1.1 기본 HTML 구성 및 CSS 적용

1.1.1 HTML 구성

기본 뼈대를 구성해주자 주로 꾸며줄 부분은 위의 login 부분이다.

<!--login-->
<div id="layer">
    <div id="content">
        <h2>로그인</h2>
    </div>
</div>

<!--header-->
<div id="wrap">
    <div id="header">
        <h1>logo</h1>
        <ul>
            <li>menu1</li>
            <li>menu2</li>
            <li>menu3</li>
            <li>menu4</li>
        </ul>
    </div>
</div>

<그림 1>


1.1.2 CSS 적용

#layer {
    position: absolute;
    display: flex;
    justify-content: center;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.35);
}

#layer > #content {
	display: flex;
    flex-direction: column;
    align-items: center;
    width: 500px;
    height: 500px;
    background: #fff;
}

#content > h2 {
    width: 100%;
    height: 20%;
}

#content > .log_in_form {
    width: 400px;
    height: 80%; 
}

<그림 2>


팝업창 이므로 다른 구성에 영향을 받지 않도록 absolute 속성을 주고, 정렬을 위해 flex 속성을 주어 정중앙에 정렬시키도록 한다. 이때 flex속성을 준 하위 상자에 너비와 높이를 주어야 원하는 대로 적용한다.

 

그 후, 내부의 h2와 로그인폼의 정렬을 위해 content에도 flex속성을 주고, 축을 아래로 바꾸고 가운데 정렬을 위해 align-items를 이용해준다.

 

1.2 box-shadow 속성

 

box-shadow는 원하는 상자의 뒤에 그림자 효과를 넣어주는 속성이다.

box-shadow의 속성값 순서는 아래와 같다.

  1. X축 방향으로 이동되는 값
  2. Y축 방향으로 이동되는 값
  3. 흐려짐 효과(blur)
  4. 그림자 크기
  5. 그림자 색상
  6. 출력위치 내,외부 결정

그림자 효과를 줄 때는 x축,y축 위치 변경후 그림자의 크기 설정, 색상 설정 순으로 적용한다.

#layer > #content {
    box-shadow: 5px 5px 15px 0px #666;
}

<그림 3> 그림자 효과


1.3 로그인 폼 기능 구현하기

로그인 폼의 기능을 구현하기 위해서 form 태그의 속성과 button, input의 속성들이 필요하다.

<div class="log_in_form">
    <form method="" action="">
        <span class="int">
            <input type="text" name="userid" id="uid" placeholder="아이디를 입력 해주세요">
        </span>
        <span class="int">
            <input type="password" name="userpw" id="upw" placeholder="비밀번호를 입력 해주세요">
        </span>
        <button type="submit">로그인</button>
    </form>
</div>

<그림 4>


1.3.1 <form>과 <input>, <button>의 속성 및 상호관계

 

<form> 태그는 항상 <fieldset>이라는 태그(시멘틱)로 감싸서 사용했으나, 요즘에는 그냥 다른 박스로 감싸서 사용하는 것을 권장한다. 

 

  • type="submit"(<button>) 아래의 action과 연동되고, submit을 사용하게 되면 action에 적힌 url로 넘어간다.

 

  • action=" "(<form>) submit과 연동되어, submit 버튼이 눌리면 url로 넘어간다.

 

  • placeholder=" "(<input>) 박스에 적힐 내용을 입력하는 칸이다.

 

  • name=" "(<input>) name의 값에 적힌 값이 action으로 사이트 이동시 <그림 5> 처럼 url 부분에 표시된다.

 

  • method=" "(<form>) get, post라는 값을 입력한다. get을 값으로 갖게 되면 url에 <그림 5> 처럼  name 값이 queryString 형태로 입력되지만, post를 값으로 입력 하면 <그림6>처럼 url에 표시되지않고 다른 곳에 같은 queryString의 형태로 입력되어 저장된다.

<그림 5>
<그림 6>


1.4 로그인 폼 마무리

기능을 구현했으면 마무리로 로그인 폼의 디자인을 꾸며 마무리 짓도록하자.

아래의 코드를 "<h2>로그인<h2>" 대신 넣고, CSS를 꾸며 마무리한다.

 

<h2>
    <span>로그인</span>
    <span>X</span>
</h2>
#layer {
    position: absolute;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.35);
}

#layer > #content {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 500px;
    height: 300px;
    background: #fff;
    box-shadow: 5px 5px 15px 0px #666;
}

#content > h2 {
    width: 100%;
    height: 20%;
    display: flex;
    justify-content: space-between; 
    padding: 15px;
    box-sizing: border-box;
    border-bottom: 1px solid #ddd;
}

#content > .log_in_form {
    width: 400px;
    height: 80%; 
}

#content > .log_in_form >form {
    display: flex;
    height: 100%;
    flex-direction: column;
    justify-content: center;
}                                

#content > .log_in_form > form > .int > input{
    width: 100%; 
    padding: 7px 14px;
    margin-bottom: 5px;
    box-sizing: border-box;
}

#content > .log_in_form > form > button[type="submit"] {
    width: 100%;
    padding: 7px 14px;
    border-radius: 0px;
    border: none;
    background: #ddd;
    font-size: 14px;
    font-weight: bold;
}

<그림 7>


여기서 주의할 점은 flex속성의 축이 column으로 바뀌었기 때문에 justify-content와 align-items가 바뀐다는 것을 숙지하도록하자. 좀 더 기능을 구현하고 싶다면 이전에 배웠던, X모양에 <label>을 이용하여 버튼을 만들 수도 있다.


2. 메뉴폼

이번에 구현해 볼 디자인은 마우스를 올리면 헤더메뉴 아래로 숨겨진 서브메뉴가 나오는 형태로 디자인 할 것이다.

<그림 8>

위의 그림처럼 Menu1이나 Menu2에 마우스를 올리면 녹색 위치에 서브메뉴가 나오도록 하는 것이다. 이 형태를 구현하는 방법은 여러방법이 있지만, 이번에는 CSS를 통해, '::before',  '::after' 를 적용하여 만들어 보도록하자.

 

2.1 HTML 구성

HTML의 구성은 다음과 같은데,  #gnb안에 .snb ul을 주어 만든 이유는 그림과 같이 #gnb의 메뉴와 .snb의 서브메뉴가 같은 선에 나오도록 구성하기 위해서이다. 나중에 메뉴를 하나더 추가 해달라는 요청이나, 제거해달라는 요청이 들어왔을 때, 손쉽게 너비를 맞출수 있기 때문이다.

<그림 9>


<div id="wrap">
    <div id="header">
        <h1>
            <a href="#">Logo</a>
        </h1>
        <ul id="gnb">
            <li>
                <a href="#">Menu1</a>
                <div class="snb">
                    <ul>
                        <li><a href="#">menu1-1</a></li>
                        <li><a href="#">menu1-2</a></li>
                        <li><a href="#">menu1-3</a></li>
                        <li><a href="#">menu1-4</a></li>
                    </ul>
                </div>
            </li>
            <li>
                <a href="#">Menu2</a>
                <div class="snb">
                    <ul>
                        <li><a href="#">menu2-1</a></li>
                        <li><a href="#">menu2-2</a></li>
                        <li><a href="#">menu2-3</a></li>
                        <li><a href="#">menu2-4</a></li>
                    </ul>
                </div>
            </li>
        </ul>
    </div>

    <div id="content">
        <h3>Hello World!</h3>
    </div>
</div>

 

<그림 10>


HTML만 작성했을 경우 <그림 10>과 같이 출력이 되는 것을 확인할 수 있다.


2.2 CSS 적용

* {
    margin: 0;
    padding: 0;
}

ul, li {
    list-style: none;
}

a {
    text-decoration: none;
}

#wrap {
    width: 100%;
}

#header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    height: 100px;
    padding: 0 30px;
    box-sizing: border-box;
    border-bottom: 1px solid #aaa;
}

#header > #gnb {
    display: flex;
}

#header > #gnb > li {
    width: 200px;
}

<그림 11>


#header에 flex속성을 주어 안의 gnb를 양끝 정렬 시키고, aling-items를 통해 가운데로 넣었다. 그 후 아래의 #content 와 편히 구분하기 위해 border-bottom을 주었다. 이제 여기에 .snb 메뉴를 display: none; 을 주어 안보이게 한 뒤 마우스를 가져다 댔을때, 보이도록 만들어 보자.

 

#header > #gnb > li > .snb {
    position: absolute;
    padding: 40px 0 0 0;
    display: none;
}

#header > #gnb > li:hover > .snb {
    display: block;
}

<그림 12>


.sbn에 position: absolute;를 주지 않으면, Menu1이 나오는 박스를 밀어내고 그 자리에 나오게 된다. 이를 해결하기 위해서는 absolute를 주어 위치를 고정시켜야 해결된다. 그 후 줄을 #content 영역에 출력하기 위해서 padding을 준다. 여기서 top을 주지 않는 이유는 absolute 속성이기 때문에, top을 주는 순간 브라우저 기준으로 정렬될 위험이 있기 때문이다. .snb에 display: none; 속성을 주고, hover를 이용하여 마우스를 올리면 display:block;으로 변해 메뉴가 <그림 12>와 같이 나오게 설정한다. 

 

2.2.1 after와 before

 

이제 서브메뉴에 색상이 나오도록 출력해야한다. 다양한 방법이 있지만, CSS에 속해 있는, after와 before 속성을 이용하여 구현해보도록 하자.

 

  • after와 before는 hover와 같이 상태 선택자를 이용하여 효과를 줄 수 있다.
  • after는 주고자하는 태그의 뒤, before는 앞에 배치된다. 이 때, CSS에서 유일하게 가상의 HTML을 구현해낸다.
  • after와 before는 일반적인 태그에 CSS를 주는 것처럼 패딩, 마진, 크기, 색상 등을 줄 수 있다.
#content > h3::before {
    content:"-";
    padding: 0 20px;
}

#content > h3::after {
    content:"*";
    padding: 0 20px;
}

<그림 13>


<그림 13> 처럼 가상의 태그를 구현해, 텍스트를 넣고 padding을 주어 공간을 구현했다

이 때, 주의할 점은 반드시 content:" "; 속성을 주어야 사용할 수 있으니 주의해야한다.

::after와 ::before의 개념은 HTML에 가상의 태그를 생성한다는게 핵심개념이다. 이를 가지고 서브메뉴에 색상이 나오도록 해보자.

#header > #gnb::before {
    content:"";
    display: none;
    position: absolute;
    left: 0px;
    top: 100px;
    width: 100%;
    height: 85px;
    background: rgba(0,0,0,0.35);
    box-shadow: 0 5px 15px -10px #000;
}

#header > #gnb:hover::before {
    display: block;
}

<그림 14>


가상의 태그(박스)라는 개념만 이해했다면, 일반적인 태그처럼 속성을 부여할 수 있으므로 어려운 점은 없다. top을 높이와 같은 크기를 주어 선을 맞춰 내려오게 했고, 색상은 투명도를 주어 뒤에 가려질 내용을 나타낼 수 있게 구현했다.


 

3. media query 문법 (반응형 웹)

브라우저에서 크기가 지정된 픽셀크기 이하로 줄어들게되면 다른 CSS를 준 화면으로 교체해준다. 예를 들면, 모바일 화면이 대표적이다. 그다지 어려운 개념은 아니지만, 시간이 많이 걸리는 작업이다. 그래도 만드는 팁이 있다면, 작은 화면을 기준으로 만들어 놓고, 큰 화면으로 가는게 좋다. 특별한 내용은 없고, 사용방법은 아래와 같다.

@media (max-width: 800px) {
    #header > #gnb {
        display: none;
    }
}

위의 CSS를 해석해보자면, 화면의 너비가 800px 까지는 #gnb를 안보이게 처리하고 800px을 넘어가면 원래 적힌 CSS 모양으로 나타난다.


<그림 15> 너비가 800px을 넘는 상태
<그림 16> 너비가 800px을 넘지 않아 #gnb가 사라졌다.