TIL 11 : CSS 실무 테크닉(1)

deli-ght·2021년 11월 19일
2

HTML/CSS

목록 보기
11/15
post-thumbnail


멋사 벌써 3주차.. 끝이 없는 HTML과 CSS... 내가 꼭 다 부수고 만다..

🪐논란의 개행 방법

개행이 디자인 목적이라면 ? <span>사용
문장의 개행을 표현하고 싶다면 <P> 사용

줄 바꿈 시, 단어 별로 짤리게 하고 싶다면 work-break:keep-all사용

현재 한국어, 일본어, 중국어에서는 normal과 break-all의 차이 없음

🪐반응형에 대비하기

높이는 되도록 설정하지 않기

추가 사항이 생기는 경우, 높이를 지정하게 되면 문제가 발생할 수 있음.
언제든 확장 가능성을 열어두기

위치값도 반응형에 맞춰

항상 반응형을 고려하기 위해서
width : calc(100% - padding값) 이런식이나

position : absolute나 fixed 상황에서 가운데로 위치를 정할 때,

top : 50%
left : 50%
transform : translate(-50%, -50%)

이렇게 페이지의 크기에 따라 반응하는 방식으로 작성하기

🪐position적용시 display 속성값

inline, inline-block 속성에 position: absolute/ float 속성을 주면, display가 block 속성이 된다.

🪐앵커태그 예비링크

기존에 앵커태그에 링크를 비워둘 때, 보통 #을 넣어뒀다. #을 넣게되면 문제점이 사이트가 재로드 된다는 점!
그렇다고 #none이렇게 적어주게 되면 none이라는 id가 생길 시 요소가 있는 위치로 이동하게 될 수 있다. (아이디를 none이라고 적지 않으면 되는거 아니냐 하겠지만, 만일의 상황도 놓치지 말기,,)

이럴 때 앵커태그에 자바 스크립트 코드를 넣을 수 있다는 점을 응용해

<a href = "javascript : void(0)">

이렇게 작성해준다. void(0) 은 undefined를 리턴해 안전하게 예비 링크로 사용할 수 있다.

🪐원래 기능 안하게 하는 법

submit 타입의 버튼이 유효성 검사를 통과하지 못하는 경우, 데이터가 제출되지 않게 하고싶다.
그렇다고 타입을 버튼으로 바꾸기엔 나중에 백엔드 연결 시 문제가 되기 때문에 꼭 submit 타입을 해야한다.

var submitBtn = document.getElementByTagName('submit')[0];

submitBtn.addEventListener('click', validate);

function validate(event){
     // Validation code here

     if(!isValid){
         event.preventDefault();
         event.stopPropagation();
     }
}

🪐input, select 박스 커스텀

input

label을 이용해 input과 연결한 뒤, input을 숨기고 새로운 디자인의 input을 만든다.
input의 :focus와 :checked 가상요소를 이용해 반응 별로 새 input의 디자인을 변경한다.

커스텀된 input의 접근성 문제

tab으로 이동 시, display:none으로 설정하면 클릭 안됨,,
특히 input요소 숨김 처리할 때 주의하기

#login .login_radio-keep-id {
  position: relative;
  font-weight: 500;
}

#login .login_radio-keep-id::before {
  display: inline-block;
  content: "";
  vertical-align: bottom;
  margin: 5px 5px 0 0;
  width: 20px;
  height: 20px;
  border: 1px solid #767676;
  border-radius: 50%;
}

#login .login_radio-keep-id::after {
  display: inline-block;
  content: "";
  position: absolute;
  top: 3px;
  left: 8px;
  width: 5.5px;
  height: 8.5px;
  border-bottom: 1px solid #767676;
  border-right: 1px solid #767676;
  transform: rotate(45deg);
}

#login #login_checkbox:checked + .login_radio-keep-id::before {
  border: 1px solid #2f80ed;
  background-color: #2f80ed;
}

#login #login_checkbox:focus + .login_radio-keep-id::before {
  box-shadow: 0 0 0 2px black;
}

#login #login_checkbox:checked + .login_radio-keep-id::after {
  border-color: #fff;
}

select

요소 자체의 구성요소가 화면에 보일지 안보일지를 결정하는 appearance 태그 사용
주로 요소들을 없애기 위해 appearance : none을 사용하는데,
다른 속성은 어떻게 동작하나 확인해보고 싶어 시도해보았으나,, 돌아가는게 없었다..
why...

select를 커스텀하는 로직을 간단히 설명하자면
메인 박스가 될 버튼 하나와 list를 이용해 datalist 버튼들을 만들고,
메인 버튼 클릭 시, datalist 버튼들을 담은 ul의 display속성이 block이 된다.
그리고 datalist의 버튼을 클릭해 선택하게 되면 클릭된 text가 메인 버튼의 text로 바뀌고
display가 다시 none이 되는 방식으로 작동하도록 한다.

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"
    >
    <link rel="stylesheet" href="style.css">
    <title>ff</title>
</head>

<body>
    <article class="selection">
        <button class="title">최애 프로그래밍 언어</button>
        <ul class="menus">
            <li class="menu"><button class="menu_btn">Python</button></li>
            <li class="menu"><button class="menu_btn">Java</button></li>
            <li class="menu"><button class="menu_btn">JavaScript</button></li>
            <li class="menu"><button class="menu_btn">C#</button></li>
            <li class="menu"><button class="menu_btn">C/C++</button></li>
        </ul>
        
            </article>

        <select name="d" id="">오늘의 메뉴</select>
        <datalist id="d">
            
        </datalist>
        <script>
            const title = document.querySelector(".title");
            const menus = document.querySelector(".menus");
            
            title.addEventListener('click', () => {
                // toggle로 설정해 클릭 시 사라졌다가 나타났다가 반복 가능
                menus.classList.toggle("is_show");
                title.classList.toggle("is_btn_open")
                
            })
            
        const menu = document.querySelectorAll(".menu");
        menu.forEach(el => {
            el.addEventListener('click' , e => {
                title.textContent = e.target.textContent;
                menus.classList.remove('is_show');
                title.classList.remove("is_btn_open")
            })
        })
    </script>
</body>

</html>

css

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.selection {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
button {
  background-color: #fff;
  border: none;
  text-align: left;
}

.title {
  padding: 0 14px;
  width: 200px;
  height: 40px;
  border: 1px solid #c4c4c4;
  border-radius: 10px;
  font-size: 12px;
  line-height: 40px;
}

.title::after {
  content: "";
  float: right;
  width: 10px;
  height: 40px;
  background-image: url(./icon-Triangle-down.png);
  background-size: contain;
  background-position: center center;
  background-repeat: no-repeat;
}

.menus {
  display: none;
  margin-top: 9px;
  padding: 4px 8px;
  width: 200px;
  list-style: none;
  border: 1px solid #c4c4c4;
  box-shadow: 4px 4px 14px rgba(0, 0, 0, 0.15);
  border-radius: 10px;
}

.is_show {
  display: inline-block;
}

.is_btn_open {
  border: 1px solid #9b51e0;
  box-shadow: 0 0 0 3px #f8e4ff;
}

.is_btn_open::after {
  background-image: url(./icon-Triangle-up.png);
}

.menu {
  margin: 5px auto;
  padding-left: 10px;
  height: 30px;
}

.menu:hover {
  background-color: #f8e4ff;
  border-radius: 8px;
}

.menu button {
  background-color: transparent;
  width: 100%;
  height: 100%;
}
profile
PRE-FE에서 PRO-FE로🚀🪐!

0개의 댓글