TIL 010 | CSS 실무 테크닉

52286 단어 TILCSSCSS

Today, I Learned.
[멋쟁이 사자처럼 프론트엔드 스쿨]에서 배운 내용 정리.
- CSS 실무 테크닉.

✏️ CSS 실무 테크닉 ✏️

1. IR(Image Replacement) 기법

웹 접근성 준수를 위해 디자인적으로는 보이지 않지만 스크린리더나 검색 엔진의 효과적인 내용 수집을 위해서 정보를 전달하는 텍스트를 html 곳곳에 숨겨두는 기법이다.

1-1. 네이버가 사용하는 기법

.blind {
	position: absolute;
	clip: rect(0 0 0 0);
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
}

현재 오늘의 집 시니어 프런트엔드 엔지니어로 계신 조은님께서 특강에서 말씀하시길 IE에서는 margin: -1px;를 작성하지 않으면 screen reader가 읽지 못하는 경우가 있기 때문에 선언해줘야 한다.

1-2. 카카오가 사용하는 기법

1-2-1. [PC용] 사용된 이미지내 의미있는 텍스트의 대체텍스트를 제공할때

.ir_pm {
	display: block;
	overflow: hidden;
	Font-size: 1px;
	line-height: 0;
	text-indent: -9999px;
}

1-2-2. [Mobile용] 사용된 이미지내 의미있는 텍스트의 대체텍스트를 제공할때

.ir_pm {
	display: block;
	overflow: hidden;
	font-size: 1px;
	line-height: 0;
	color: transparent;
}

1-2-3. 스크린리더가 읽을 필요는 없지만  마크업 구조상 필요할때

.screen_out {
	overflow: hidden;
	position: absolute;
	width: 0;
	height: 0;
	line-height: 0;
	text-indent: -9999px;
}

1-2-4. 중요한 이미지 대체텍스트로 이미지 off 시 에도 대체 텍스트를 보여주고자 할때

.ir_wa {
	display: block;
	overflow: hidden;
	position: relative;
	z-index: -1;
	width: 100%;
	height: 100%
}

2. Custom

실무에서는 디자인적인 개성을 주기 위해 input 요소나 select 박스를 정해진 브라우저 스타일과 다르게 표현하는 경우가 있다고 한다.

2-1. Input checkbox

<!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="../reset.css">
    <title>input custom</title>
    <style>
        .blind {
            position: absolute;
            clip: rect(0, 0, 0);
            width: 1px;
            height: 1px;
            margin: -1px;
            overflow: hidden;
        }

        .labl-hold {
            display: block;
            height: 22px;
            margin: 17px 0 21px;
            text-align: left;
            font-weight: 500;
            font-size: 16px;
            line-height: 20px;
            color: #767676;
            cursor: pointer;
        }
        
        .labl-hold::before {
            display: inline-block;
            content: "";
            width: 22px;
            height: 22px;
            margin-right: 8px;
            vertical-align: -5px;
            background-image: url("./img/icon_check_empty.png") ;
        }

        .inp-hold:checked + .labl-hold::before {
            background-image: url("./img/icon_check.png") ;
        }
    </style>
</head>
<body>
    <!-- blind 클래스로 요소를 숨겨줍니다. -->
    <input type="checkbox" id="inpHold" class="inp-hold blind">
    <label for="inpHold" class="labl-hold">로그인 상태 유지</label>
</body>
</html>

input 요소인 checkbox를 ir 기법을 사용하여 숨긴 후
label의 가상요소에 이미지를 삽입하여 custom한 것이다.

2-2. Input checkbox

<!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="../reset.css">
    <title>select custom</title>
    <style>
        .btn-select {
            width: 200px;
            height: 30px;
            background: hotpink;
            color: #fff;
        }

        .list-member {
            display: none;
            width: 200px;
            height: 30px;
        }

        .list-member.on {
            display: block;
        }

        .btn-select:active + .list-member {
            display: block;
        }

        .list-member li {
            height: 30px;
            width: 200px;
        }

        .list-member li button {
            display: block;
            height: 100%;
            width: 100%;
            background-color: #fff;
            border: 1px solid black;
            border-top: none;
        }

        .list-member li button:hover {
            background-color: bisque;
        }
    </style>
</head>
<body>
    <button class="btn-select">당신이 생각하는 최고의 운동은?</button>
    <ul class="list-member">
        <li><button type="button">데드리프트</button></li>
        <li><button type="button">벤치프레스</button></li>
        <li><button type="button">스쿼트</button></li>
        <li><button type="button">숄더프레스</button></li>
    </ul>
    
    <script>
        const btn = document.querySelector('.btn-select');
        const list = document.querySelector('.list-member');
        btn.addEventListener('click', () => {
            list.classList.toggle('on');
        });
        list.addEventListener('click', (event) => {
            if (event.target.nodeName === "BUTTON") {
                btn.innerText = event.target.innerText;
                list.classList.remove('on');
            }
        });
    </script>
</body>
</html>

2-3. 실습 예제

Code
간단한 js를 사용하여 display: none;으로 숨겨져 있던 리스트를 버튼 클릭 시 display: block;으로 바꿔주며 마치 checklist 처럼 보이게 custom한 것이다.

3. CSS Sprite

여러가지의 이미지를 하나의 이미지 파일안에 배치하여 이미지로드 부담을 줄이는 방법이다.

image sprite 생성 사이트 : image sprite generator

참고 : 제주코딩베이스캠프

4. Retina 디스플레이 대응법

4-1. Retina 란?

특정한 시야 거리에서 인간의 눈으로는 화소를 구분할 수 없는 화소 밀도(300 PPI가 넘을 경우)를 가진 애플 LCD 제품의 브랜드 이름이다.

4-2. 원인은 무엇일까?

Retina(고해상도 화면)로 넘어오면서 논리픽셀(css에서 표현하는 화소의 기본 단위)과 물리픽셀(디바이스가 실제로 처리할 수 있는 화소의 기본 단위)의 차이가 발생하지만 브라우저는 css에서 정의한 픽셀만큼 이미지를 렌더링 해야하기 때문에 원래는 물리픽셀에 맞게 렌더링된 이미지가 논리픽셀 만큼 커져버리게 되기 때문에 아래와 같은 차이가 발생하게 된다.

4-3. 해결 방법

화면에 표현하고자 하는 이미지 사이즈의 2배 되는 이미지로 대체한다.
(image sprite 생성 사이트 : image sprite generator)

5. 반응형 컨텐츠

5-1. 반응형 이미지

5-1-1. width: 100%

viewport의 넓이를 기준으로 100%

5-1-2. max-width: 100%

원본 이미지의 넓이를 기준으로 100%

<!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="../reset.css">
    <title>반응형 이미지</title>
    <style>
        /* 반응형 이미지 */
        img {
            /* viewport 기준 100% */
            /* width: 100%; */
            /* 원본 이미지 기준 100% */
            max-width: 100%;
        }
    </style>
</head>
<body>
    <img src="./img/example.jpg" alt="">
</body>
</html>

5-2. 반응형 백그라운드 이미지

5-2-1. 컨테이너 width의 50%를 차지하고 비율을 유지하며 height를 auto 설정

5-2-2. 컨테이너 width의 50%를 차지하고 비율을 유지하며 height를 auto 설정

5-2-3. 컨테이너 전체를 덮고 이미지가 잘림

<!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="../reset.css">
    <title>반응형 이미지</title>
    <style>
        /* 반응형 백그라운드 이미지 */
        div {
            width: 100vw;
            height: 100vh;
            /* 컨테이너의 width의 50%를 차지하고 비율을 유지하며 height를 auto 설정 */
            /* background: url("./img/example.jpg") 0/50% auto no-repeat; */
            /* 컨테이너 전체를 덮지만 이미지를 자르지 않게 유지. */
            /* background: url("./img/example.jpg") 0/contain no-repeat; */
            /* 컨테이너 전체를 덮고 이미지가 잘림 */
            background: url("./img/example.jpg") center center/cover no-repeat;
        }
    </style>
</head>
<body>
    <div></div>
</body>
</html>

5-3. 반응형 동영상

동영상 출처: SMTOWN YOUTUBE

<!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="../reset.css">
    <title>반응형 동영상</title>
    <style>
        div {
            position: relative;
            padding-top: 56.25%;
        } 

        iframe {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <div>
        <iframe width="950" height="534" src="https://www.youtube.com/embed/WPdWvnAAurg?autoplay=1&muted=1&controls=1&loop=1&playlist=WPdWvnAAurg" title="YouTube video player" frameborder="0" allowfullscreen></iframe>
    </div>
</body>
</html>

16:9 비율의 동영상을 반응형으로 만들기 위해서 padding-top: 56.25%;
(9/16 = 56.25%)

좋은 웹페이지 즐겨찾기