Vanilla JS Toy 프로젝트 1. Form Validator - CSS편(2)

falconlee236

·

2022. 1. 7. 23:35

반응형

여기에 올라온 모든 프로젝트와 소스코드는 here 여기서 확인할 수 있다.

vanilla javascript Toy project 1. Form Validator


css는 정리할 내용이 많아서 부득이하게 나눠서 글을 올릴것 같다. 이번 글로 css는 끝내고 다음 글에서는 javascript를 어떻게 구성할지 알아보자. 이번 글에서 소개할 내용은 다음과 같다.

  1. flex container 내부 설정
  2. css의 box layout에 있는 margin과 padding 조절
  3. 각 요소의 위치 설정
반응형

1. flex container 내부 설정


flex container에서는 주 축이 지나가는 크기를 설정할 필요가 없다. 왜냐하면 container에 들어있는 element들의 padding, margin과 같은 box layout의 속성값을 변경하면 자동으로 유연(flex)하게 크기가 늘어나기 때문이다. 이 container의 색깔은 마찬가지로 background-color 속성을 사용하고, 주축이 지나가는 곳은 크기를 조절할 필요가 없다고 했으니 너비 설정만 하면되기 때문에 너비 속성은 주어진 웹사이트와 비교하면서 맞추면 된다. 이제 소개할 것은 모서리 즉 border이다.

  1. 현재 container에 있는 box는 테두리가 원형이고, 그림자가 져있는 것을 알 수 있다.
    • border-radius 속성은 요소 테두리 경계의 꼭짓점을 둥글게 만든다. 하나의 값을 사용하면 원형 꼭짓점을 적용할 수 있다. 원래 이 속성에는 각 꼭짓점마다 설정할 수 있는 요소가 있지만 여기서는 모든 꼭짓점을 원형으로 만들고 싶기 때문에 이 속성에 한가지 값만을 적용하면 모든 테두리에 px값 만큼 테두리가 만들어진다.
    • border-shadown 속성은 요소 테두리 경계에 그림자를 만든다. 2개의 값부터 최대 4개의 값이 주어지고, 그 다음에 선택사항으로 insert와 color값이 차례로 주어진다.
      • 두 개의 값을 사용하면 <offset-x><offset-y>로 분석한다. 이때 x값이 양수이면 오른쪽, y값이 양수이면 아래쪽으로 그림자가 진다.
      • 세 번째 값이 주어지면 <blur-radius>로 분석한다. 값이 크면 클수록 그림자 테두리가 흐려진다. 따라서 크기는 더 커지고 색은 더 밝아지며 음수값은 사용할 수 없다.
      • 네 번째 값이 주어지면 <spread-radius>로 분석한다. 양수 값은 그림자 크기가 더 커지고 확산하며, 음수 값은 그림자가 줄어든다.
  1. container에서 처음 설정할 부분은 제목인 h2태그이다.
    • 현재 이 h2태그가 있는 글상자 요소가 맨 위에 있다고 생각하면 되는데 글 상자에 있는 글을 가운데로 정렬하려면 text-align 속성을 center로 설정해주면 된다.
    • 글 상자의 위치를 조정해야 하는데 위에서 말했듯이 margin값과 padding값을 조정해서 위치를 수정한다고 했다. 글상자 위쪽과 아래쪽에 빈 공간이 있으므로 margin값의 위쪽과 아래쪽 값을 바꾸면 될것 같은데 이미 fiex 주축 정렬을 할 때 center로 했기 때문에 맨 위쪽과 맨 아래쪽 마진은 이미 동일한 크기로 정렬 되어있다. 따라서 우리가 조정해야 할 값은 아래쪽 margin이다.
      • margin과 padding속성에 들어갈 값은 서로 양식이 같기 때문에 한번에 설명하자.
        • 한 개의 값을 사용하면 모든 네 면의 여백을 설정
        • 두 개의 값을 사용하면 첫번째는 위와 아래, 두번째는 왼쪽과 오른쪽 여백을 설정한다.
        • 세 개의 값을 사용하면 첫번째는 , 두번째는 왼쪽과 오른쪽, 세번째는 아래 여백을 설정한다.
        • 네개의 값을 지정하면 각각 상, 우, 하, 좌 방향으로 여백을 지정한다. (시계방향)
반응형

2. form tag 내부 설정


위에서 설명한 요소는 전체적인 container 테두리과 글상자에 적용된 css속성에 대해서 설명했다. 이제 본격적으로 javascript에 의해 동작이 이루어질 form태그 안에 있는 요소들에 적용된 css속성에 대해서 알아보자.

  1. form 태그는 글상자와 다른 요소로 따로 만들어졌기 때문에 form 태그를 의미하는 box 요소의 위치를 맞춰야 하고, 이 box는 padding 값을 조정해서 위치를 설정한다. padding과 margin은 border 속성이 있어야 의미가 있는데, 여기서는 border 속성이 없기 때문에 어느것을 써도 상관이 없다.
  2. form 태그 안에 있는 입력창들과 text, error message값은 모두 form-control class에 묶여있다. 따라서 이 class의 css값을 조정하면 4개의 입력 모두 한번에 위치가 조정될 것이다.
    • position 속성은 css에서 기본값인 static을 포함해서 5개 값을 가지고 있다.
      • static: 요소를 나열한 순서대로 배치하며 브라우저가 임의대로 조화롭게 설정한다. 따라서 top, right, bottom, left 와 같은 속성을 사용할 수 없다. 보통 display 속성에 따라 배치가 결정된다.
      • relative: static이었을 때 배치되는 위치를 기준으로 상대적 위치를 지정할 수 있는 속성이다.
      • absolute: 문서의 배치 흐름에 상관없이 가장 가까운 부모 요소, 조상 요소중 position 특성이 relative 인 요소를 기준으로 위치를 좌표로 배치한다.
      • fixed: 브라우저 창을 기준으로 해서 위치를 좌표로 결정한다. 이때 기준점은 브라우저 왼쪽 위 꼭짓점
      • sticky: 기준점 이상을 넘지 않으면 relative 처럼 동작하다가 그 이상을 넘게되면 fixed처럼 동작하는 값이다. 그러다 스크롤이 scroll 박스 밖으로 벗어나면 그 위치에서 정지한다.
    • label요소는 h1과 같은 요소와 다르게 그냥 inline text요소로 취급되기 때문에 display: inline 처럼 배치되서 한줄에 input과 label이 배치가 된다. 심지어 inline요소는 width, height, padding과 같은 box model 속성이 적용이 안된다. 따라서 display: block 속성을 사용해서 block 요소로 변환해서 label요소가 한줄을 차지하게 해야한다. 그 후 아래 margin값을 조정해서 위치를 조정한다.
      • display: block: 앞 뒤 줄바꿈이 들어가 다른 요소들을 다른 줄로 밀어내고 혼자 한 줄을 차지한다. 기본적으로 적용되는 element는 <div>, <p>, <h1>이다.
      • display: inline: 앞 뒤 줄바꿈이 없이 한 줄에 다른 요소와 나란히 배치된다. 대표적인 inline 요소로는 <span>, <a>, <em> 태그가 있다. 주의할 점은 width와 height 속성은 무시되며, margin과 padding속성은 좌우 간격만 반영되고 상하 간격은 반영이 안된다.
  1. input요소는 지금 테두리가 회색으로 되어있고 오른쪽으로 꽉 차있다. 그리고 클릭을 하면 색깔이 회색으로 바뀌며 주변 외곽선이 생기지 않는다.
    • 테두리를 설정하는 속성은 border이고 이 속성에는 설정할 수 있는 다음 값 중 1개에서 3개까지 선택해서 지정할 수 있으며 순서는 영향을 주지 않는다.
      • <line-width>: 테두리의 굵기로 기본값은 medium이다.
        • thin: 얇은 테두리
        • medium: 중간 테두리
        • thick: 굵은 테두리
      • <line-style>: 테두리의 스타일로 기본값은 none이다.
      • <color>: 테두리의 색상으로 기본값은 currentcolor이다.
    • 요소의 너비를 부모태그를 기준으로 설정하고 싶으면 퍼센트 값을 사용하면된다. 100%는 부모 태그를 기준으로 100%를 사용하겠다는 뜻이다.
    • 원래라면 요소를 클릭할때 어떤 색상이 변경된다와 같은 이벤트를 다룰려면 javascript에서 event 핸들러를 등록해야 하지만 css의 의사 클래스를 이용해서 간편하게 설정할 수 있다.
      • :focus: 보통 사용자가 요소를 클릭, 탭, 키보드 Tab 키로 선택했을 때 발동한다.
    • 외곽선을 지울려면 outline: 0으로 지정하면 된다.
  2. 사용자가 input태그에 어떤 값을 입력했는지에 따라 태두리 색깔이 바뀌고, error 메시지가 출력되기도 한다.
    • 이 부분은 javascript에서 주로 다룰 것인데, 먼저 기본 값인 form-control 클래스값을 가지고 있는데, 만약 입력이 성공적으로 이루어지면 거기에 sucess라는 클래스를 추가한다. 그리고 css에서는 두 클래스가 동시에 존재하는 경우에 초록색 테두리를 그리게 한다. 두 클래스가 동시에 존재할때 필요한 선택자는 두 클래스값을 붙여서 쓰는 것이다. A클래스와 B클래스가 동시에 존재할때 선택자는 .A.B이다.
    • 만약 입력이 잘못됐으면 거기에 error라는 클래스를 추가하고 css에서는 두 클래스가 동시에 존재하는 경우에 빨간색 테두리를 그리게 한다.
    • 위에서 설정한 전역변수값을 적용하는 방법은 var()함수 안에 전역 변수를 넣으면 적용이 된다.
    • 마찬가지로 입력이 잘못됐으면 error메시지도 출력하는데, 미리 빨간색으로 error메시지를 적어놓은 다음 평상시에는 visibility 속성을 hidden으로 해서 숨겨놓은 다음 입력이 잘못될때 error클래스가 추가될 것이고 거기에 있는 small 태그에 visibility 값을 visible으로 하면 쉽게 할 수 있다.
  3. 마지막으로 button 태그에서는 앞에서 설명한 내용을 모두 읽어봤으면 쉽게 만들 수 있을 것이다. 한 가지 알아둘 것은 button 위에 손 모양으로 바뀌게 하는 법은 cursor: pointer로 속성값을 설정하면 된다.

여기까지 진행했으면 최종 css 코드는 다음과 같다.

반응형
@import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');

:root{
    --success-color: #2ecc71;
    --error-color: #e74c3c;
}

*{
    box-sizing: border-box;
    /*border-box = padding, border, content를 모두 합쳐서 width와 height를 결정*/
    /*content-box = 오직 content영역에만 width, height 영향*/
}

body{
    background-color: #f9fafb;
    font-family: 'Open Sans', sans-serif;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    margin: 0;
}

.container{
    background-color: white;
    border-radius: 5px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
    width: 400px;
}

h2{
    text-align: center;
    margin: 0 0 20px;
    /*margin: [margin-top] [margin-left = margin-right] [margin-bottom];*/
}

.form{
    padding: 30px 40px;
    /*padding: [margin-top = margin-bottom] [margin-left = margin-right];*/
}

.form-control{
    margin-bottom: 10px;
    padding-bottom: 20px;
    position: relative;
    /*기본값의 위치를 기준으로 상대적 위치*/
}

/*자손 선택자*/
.form-control label{
    color: #777;
    display: block;
    margin-bottom: 5px;
}

.form-control input{
    border: 2px solid #f0f0f0;
    border-radius: 4px;
    display: block;
    width: 100%;/*부모태그의 100%를 사용하겠다*/
    padding: 10px;
    font-size: 14px;
}

.form-control input:focus{
    outline: 0;
    border-color: #777;
}

/*모든 선택자가 적용된 경우*/
.form-control.success input{
    border-color: var(--success-color);
}

.form-control.error input{
    border-color: var(--error-color);
}

.form-control small{
    color: var(--error-color);
    /*상위 요소 기준 위치 설정*/
    position: absolute;
    bottom: 0;
    left: 0;
    visibility: hidden;
}

.form-control.error small{
    visibility: visible;
}

.form button{
    cursor: pointer;
    background-color: #3498db;
    border: 2px solid #3498db;
    border-radius: 4px;
    color: #fff;
    display: block;
    font-size: 16px;
    padding: 10px;
    margin-top: 20px;
    width: 100%;
}
반응형