HTML/CSS review
Tags: html, css
Published: 2021-11-19 20:21:22



#Things to remember
- Don't specify height for (parent)element unless it's necessary because if it has height value, there are more possibility that it might break the UI. (If content changes for example, when elements get added within the container that has height value, it will break the UI). It needs flexibility to maintain the code for future use. Think about the content that will be inside the element.
- If you give position: absolute or float to an element, it behaves like block element.
- Think about meaning of tags when writing code. for example, it's okay to use <code><strong>p</strong></code> tag even if it's one sentence. If it's important, use <code><strong>strong</strong></code>. Use <code><strong>em</strong></code> if it's less important than strong but you still want to stress it. But <code><strong>span</strong></code> and <code><strong>div</strong></code> have no meaning. It's okay to use them if it's only for styling but avoid if not.
- when <code><strong>a</strong></code> tag is empty, if you write <code><strong>a href="#"</strong></code>, it reload the page and if you <code><strong>a href="#none"</strong></code>, it can go to the element id none if id none get created. void(0) returns undefined, so you can use it like below for <code><strong>a</strong></code> tag until you have link for it.
```html
  <a href="javascript:void(0)" class="link-signup">회원가입</a>
```
- Screen reader will treat it like it doesn't exist if an element is <code><strong>display: none;</strong></code>
```html
<a href="">
 <img>
</a>
```
- from above code, if you set the location of <code><strong>img</strong></code> to position, <code><strong>img</strong></code> isn't normal-flow anymore. <code><strong>a</strong></code> tag doesn't recognise it's child anymore and in this case, you cannot focus this element when using tab key. If you want to move the location, give position to <code><strong>a</strong></code> tag instead.


#Web Accessibility
![tabkey-access](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8y9bzu8ua2skvlidi1g.gif)
The close button on the top right is next to the heading but should think about web accessibility. It's more natural to be read after login button like the image above not right after the heading which doesn't consider the user.
If closing button is written after the login button, it will be read by screen reader after all of above elements are read by flow. (even if you write it under login button, you can move it to the top left using css) <u>When writing html, think about user and web accessibility not only the layout!</u>

Also, When you see the image above, you can see the blue border when checkbox is focused. But actually, it's an image that's placed on the top of checkbox input and input is taken away from screen using css. So if you don't style it, you can't see if it's focused or not when it's focused.

```html
<input type="checkbox" id="inpHold" class="inp-hold txt-hide">
<label for="inpHold" class="labl-hold">로그인 상태 유지</label>
```
```css
/* This takes away input.checkbox from the view */
.txt-hide {
  position: absolute;
  clip: rect(0 0 0 0);
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
}

/* This displays the blue border around the checkbox. It's for web accessibility. */
.form-login .inp-hold:focus + .labl-hold::before {
  outline: 2px solid #2f80ed;
  /* 2px of space from outline to border */
  /* outline-offset: 2px; */
  border-radius: 50%;
}

```

#calc()
calc() is good to use for responsive design.

```css
width: calc(100% - 400px);
width: calc(80vw - 400px);
width: calc(70% - 400px);
/* use small one between them */
width: min(500px, 50vw);
min-width: 500px;
width: 200vmin;
width: max(500px, 50vw);
```

#CSS Module
If you make css module, you can avoid repeating code and also, can reuse the code just by giving class name!
<strong>example</strong>
```html
<!DOCTYPE html>
<html lang="ko">

<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>Document</title>
    <link rel="stylesheet" href="login_style/reset.css">
    <link rel="stylesheet" href="login_style/style_module.css">
    <style>
        /* ul > li (reset.css 에서느는 ul안에 li 들어있어야 해당되서 따로 추가함) */
        li {
            list-style: none;
        }
    </style>
</head>

<body>
    <p>버튼 모듈</p>
    <li><a href="" class="icon-google link-sns-login">구글 계정으로 로그인</a></li>
    <li><a href="" class="icon-naver link-sns-login">네이버 계정으로 로그인</a></li>
    <li><a href="" class="icon-facebook link-sns-login">페이스북 계정으로 로그인</a></li>
    <li><a href="" class="icon-kakao link-sns-login">카카오 계정으로 로그인</a></li>

    <button type="button" class="btn-login">로그인</button>
    <button type="button" class="btn-close"><img src="images-login/close.png" alt="로그인 닫기"></button>

    <p>인풋 모듈</p>
    <fieldset class="module-inp module-inp-id error">
        <label for="inpId" class="txt-hide">아이디</label>
        <input type="text" class="inp-login" id="inpId" placeholder="아이디">
        <strong class="inp-error">아이디를 입력해 주세요.</strong>
    </fieldset>
    <fieldset class="module-inp error">
        <label for="inpPw" class="txt-hide">비밀번호</label>
        <input type="password" class="inp-login" id="inpPw" placeholder="비밀번호">
        <strong class="inp-error">아이디 혹은 비밀번호과 일치하지 않습니다.</strong>
    </fieldset>
</body>

</html>
```

```css
.btn-login {
  width: 100%;
  padding: 17px 0 15px;
  font-weight: bold;
  font-size: 22px;
  line-height: 28px;
  background-color: #2f80ed;
  border-radius: 5px;
  border: none;
  color: #fff;
  cursor: pointer;
}

.btn-close {
  width: 16px;
  height: 16px;
  padding: 0;
  background-color: #fff;
  border: none;
  cursor: pointer;
}

.module-inp .inp-login {
  display: block;
  width: 100%;
  padding: 15px 0 15px 16px;
  border: 1px solid #c4c4c4;
  box-sizing: border-box;
  border-radius: 5px;
  font-weight: 500;
  font-size: 16px;
  line-height: 20px;
}
.module-inp.module-inp-id.error .inp-login {
  border: 2px solid #f4492e;
}

.module-inp .inp-error {
  display: none;
  margin: 6px 0 0 4px;
  font-size: 14px;
  line-height: 18px;
  color: #f4492e;
}

.module-inp.error .inp-error {
  display: block;
}

/* sibling 있을때만 margin 생김 */
.module-inp + .module-inp {
  margin-top: 10px;
}

.link-sns-login {
  display: block;
  padding: 15px 0 16px 15px;
  font-weight: 500;
  font-size: 16px;
  line-height: 20px;
  color: #767676;
  text-decoration: none;
  text-align: center;
  border: 1px solid #767676;
  box-sizing: border-box;
  border-radius: 5px;
  text-indent: -38px;
}

/* before은 first child after는 last child */
.link-sns-login::before {
  display: block;
  content: "";
  float: left;
  width: 22px;
  height: 22px;
  margin-left: 16px;
  background-image: url(../images-login/google.png);
  background-size: 22px;
}

.link-sns-login.icon-naver {
  border-color: #00bf18;
}
.link-sns-login.icon-naver::before {
  background-image: url(../images-login/naver.png);
}

.link-sns-login.icon-facebook {
  border-color: #2d9cdb;
}
.link-sns-login.icon-facebook::before {
  background-image: url(../images-login/facebook.png);
  background-repeat: no-repeat;
  background-position: center;
  background-size: 12px;
}

.link-sns-login.icon-kakao {
  border-color: #f2c94c;
}
.link-sns-login.icon-kakao::before {
  background-image: url(../images-login/kakao.png);
}
```