HTML Native Validation

  • 브라우저에서 지원하는, html 에 쓰는 !
  • input-type, require, min, max, length
  • 퍼포먼스가 좋다 → 즉각적인 반응!
  • 커스텀이 힘들고 제한적 → 복잡한 동작 불가능

basic

<form action="">
	<label for="stuff">원하는 수량을 입력하세요 : </label>
	<input id="stuff" type="number" min="3" max="10">

	<label for="stuff2">이메일을 입력하세요 :</label>
	<input id="stuff2" type="email" required minlength="10" maxlength="20">
	<button type="submit">제출</button>
</form>
  • type : input 타입
  • min, max : number 최소값, 최대값 지정
  • minlength, maxlength : 문자 최소, 최소 길이 지정
  • required : 필수 입력

 

validation 가상선택요소로 스타일 주기

  • required 일 때
input:required {
	border: 3px solid green;
}
  • 올바르지 못한 입력을 받았을 때
input:invalid {
	border: 3px solid red;
}
  • 값이 올바를 때
input:valid {
	border: 3px solid blue;
}
  • 중첩 사용
input:required:invalid {
	background-color: hotpink;
}

 

pattern - 정규표현식

<label for="">사과를 입력하세요</label>
<input type="text" pattern="사과">

<label for="">사과와 배 중 하나를 입력하세요</label>
<input type="text" pattern="사과|배">

<label for="">모든 문자(숫자+글자)중에 세글자만 입력하세요</label>
<input type="text" pattern="...">

<label for="">첫번째 문자는 사, 과, 배, 두번째 문자는 1, 2, 3만 입력가능합니다.</label>
<input type="text" pattern="[사,과,배][1-3]">

<label for="">한글만 입력가능합니다.</label>
<input type="text" pattern="[ㄱ-ㅎㅏ-ㅣ가-힣]">

<label for="">한글,숫자 글자수 제한 없이 입력가능합니다.</label>
<input type="text" pattern="[ㄱ-ㅎㅏ-ㅣ가-힣0-9]*">

<label for="">한글,숫자 한글자-다섯글자만 입력가능합니다.</label>
<input type="text" pattern="[ㄱ-ㅎㅏ-ㅣ가-힣0-9]{1-5}">

<label for="">한글,숫자 다섯글자 이상 입력가능합니다.</label>
<input type="text" pattern="[ㄱ-ㅎㅏ-ㅣ가-힣0-9]{5,}">

<label for="">주민등록 번호를 입력해주세요.</label>
<input type="text" pattern="[0-9]{13}">

<label for="">이메일 주소를 입력해주세요.</label>
<input type="email" pattern="[a-zA-Z0-9]*@[a-z]*\\.[a-z]*">

 

JS Validation

  • 다양한 커스터마이징 가능
  • html 보다는 느리다 → 사용자가 체감할 정도는 아니다
  • validation 라이브러리는 다양하고 많다.

Client-side form validation - Learn web development | MDN

 

Client-side form validation - Learn web development | MDN

Client-side form validation sometimes requires JavaScript if you want to customize styling and error messages, but it always requires you to think carefully about the user. Always remember to help your users correct the data they provide. To that end, be s

developer.mozilla.org

 

JS Validity 확인하기

<form action="">
 <input type="email" required>
</form>
const inp = document.querySelector('input');
inp.addEventListener('input', () => {
 console.log(inp.validity);
})

  • typeMismatch : input 타입이 맞는지 확인
  • patternMismatch : pattern 조건 확인
  • rangeOverflow, rangeUnderflow : max, min 조건 확인
  • tooLong, tooShort : maxlength, minlength 조건 확인
  • vaild : 모든 유효성을 통과 했는가 → 이게 true가 되면 통과!
// 모든 요소 적용하기
const inps = document.querySelectorAll('input');
inps.forEach((inp) => {
	inp.addEventListener('input', () => {
		console.log(inp.validity);
	})
})

 

Custom Validity

HTMLObjectElement: setCustomValidity() method - Web APIs | MDN

 

HTMLObjectElement: setCustomValidity() method - Web APIs | MDN

The setCustomValidity() method of the HTMLObjectElement interface sets a custom validity message for the element.

developer.mozilla.org

 

  • 알림 메세지 변경하기

기본 알람 메세지

const inp = document.querySelector('input');
inp.setCustomValidity('입력이 아무래도 뭔가 이상한 느낌이 들어요');

변경된 알람 메세지

⇒ 하지만 제출이 되지 않는다 !

 

  • 알림 메세지 분기처리로 해결
const btn = document.querySelector('button');
const inp = document.querySelector('input');
btn.addEventListener('click', () => {
	if (inp.validity.typeMismatch) {
		inp.setCustomValidity('알맞은 양식의 이메일 주소를 입력하세요!');
	} else {
		inp.setCustomValidity('');
	}
})

 

  • 전체 input 요소에 적용하기
const btn = document.querySelector('button');
const inps = document.querySelectorAll('input');
btn.addEventListener('click', () => {
	inps.forEach((inp) => {
		validate(inp);
	})
})

function validate(target) {
	if (target.validity.valueMissing) {
		target.setCustomValidity('값이 없습니다. 정신 차리자');
	} else if (target.validity.typeMismatch) {
		target.setCustomValidity('알맞은 양식의 데이터를 입력하세요!');
	} else {
		target.setCustomValidity('');
	}
}

회고

프로젝트 시작전 form validation에 대해 다시 짚어가는 시간을 가졌다. 마침 HTML/CSS 정규 수업때 놓친게 많은 부분이었는데 추가적인 기능까지 알 수 있어 정말 유익했다. DOM 쓰는게 능숙하지 않아서 JS 커스텀 배운다고 할 때 겁먹었는데 생각보다 간단해서 이해하기 쉬웠다. 이 코드들은 두고두고 많이 활용될 것 같다ㅎ-ㅎ

 

jQuery란? 라이브러리

라이브러리란? → 자주 사용하는 코드를 재사용 할 수 있는 형태로 가공하여 프로그래밍 효율을 높여주는 코드들

 

jQuery 사용하기

HTML 파일에 jQuery 연결하기

jQuery CDN - Latest Stable Versions

 

jQuery CDN

The integrity and crossorigin attributes are used for Subresource Integrity (SRI) checking. This allows browsers to ensure that resources hosted on third-party servers have not been tampered with. Use of SRI is recommended as a best-practice, whenever libr

releases.jquery.com

 

jQuery는 선택하고 실행한다.

// 선택. 실행.
$('p').hide();

 

  • 예제 코드들
// p 엘리먼트를 선택하고 숨긴다.
$("p").hide();

// test id를 가진 엘리먼트를 선택하고 표시한다.
$("#test").show();

// test class를 가진 엘리먼트를 선택하고 해당 엘리먼트의 내용을 변경한다.
$('.test').text('hello world');

// test id를 가진 엘리먼트의 내용을 변경한다.
$('#test').html('<b>hello</b> world');

// test id를 가진 엘리먼트를 선택하고 폰트컬러를 red로 변경한다.
$('#test').css('color', 'red');

// img 엘리먼트를 선택하고 src속성의 값을 변경한다.
$('img').attr('src', 'a.jpg');

// one 클래스 하위에 존재하는 two 클래스를 가진 엘리먼트를 선택하고 내용을 변경한다.
$('.one .two').text('hello world');

// two라는 id를 가진 p 엘리먼트를 선택하고 내용을 변경한다.
$('p#two').text('hello world');

// test class를 가진 엘리먼트를 클릭시에 alert을 실행한다.
$(".test").click(function(){
	alert("클릭!");
});

// test class를 가진 엘리먼트를 클릭시에 해당 엘리먼트의 폰트 컬러를 red로 변경한다.
$(".test").click(function(){
	$(this).css('color', 'red');
});

 

  • 버전별 차이
    • jquery-1.x : 구형 브라우저 대부분 지원, 가장 안정적인 버전, 최신 버전과 호완문제가 있어 migrate를 함께 넣어주어야 합니다.
    • jquery-2.x : 익스플로러 8버전 버림, 따라서 파일 크기 감소. 9버전 이상을 호환할 것이라면 2.x를 사용할 것!
    • jquery-3.x : Promises와 ajax, when, data 등 여러 최신 플러그인과 HTML5 호환

 

jQuery 선택자(Selector)

// p 태그 선택하기
$("p")

// div태그안에 있는 p태그 선택하기
$("div p")

// id가 main인 엘리먼트를 선택하기
$("#title")

// class가 btn인 엘리먼트를 선택하기
$(".btn")

// 여러 클래스를 가진 요소 선택하기
$(".class1.class2")

// 다른 태그 내에 있는 특정 태그를 가진 모든 요소 선택하기
$("ul li a")

// p 아래 모든 a 요소
$("ul a")

// p 바로 아래 자식인 a 요소
$("ul > a")

 

jQuery 필터

  • 미리 알아두면 좋은 약어들
    • eq - equal ( = )
    • ne - not equal ( <> )
    • lt - little ( < ), stands for the less-than sign
    • (없음) le - little or equal ( <= ), less-than or equals sign
    • gt - greater ( > ), stands for the greater-than sign
    • (없음) ge - greater or equal ( >= ), greater-than or equals sign

 

기본 필터

  • :eq(index) $("li").eq(3).css("color", "red" );
  • :even(짝수, 2븐 == 짝수)
  • :odd(홀수, odd는 3글자 홀수)
  • :first
  • :last
  • :gt(index) - 큰 숫자 선택 $("li:gt(2)").css( "backgroundColor", "yellow");
  • :lt(index) - 작은 숫자 선택 $("li:lt(2)").css( "backgroundColor", "yellow");
  • :not(filter) - $("input:not(:checked)+span").css( "background-color", "yellow" );

⇒ index는 음수도 허락한다.

 

차일드 필터

  • :first-child, :last-child
  • :nth-child(2)
  • :nth-child(even), :nth-child(odd)
  • :nth-child(3n)
// li태그중 3번째
// $("li").eq(3).css("color", "red" );

// li태그중 6번째 이상
// $("li:gt(6)").css("color", "red");

// li태그중 2번째 마다
// $("li:nth-child(2n)").css("color", "red");

// li태그중 3번째 마다
// $("li:nth-child(3n)").css("color", "red");

// li태그중 첫번째
// $("li:first").css("color", "red");

// li태그중 마지막
// $("li:last").css("color", "red");

// li태그중 짝수번째
// $("li:even").css("color", "red");

// li태그중 홀수번째
// $("li:odd").css("color", "red");

 

속성 필터

  • 해당하는 속성을 가지고 있는 노드
    • [href]
    • input[name]
  • 해당 속성의 값이 문자열과 일치하는 노드
    • input[name='newmilk']
  • 해당 속성의 값에서 주어진 문자열을 포함하고 있는 노드
    • input[name*='man’]
// href 속성이 있는 요소
$("[href]").css("background-color", "red");

// input 중 name속성이 있는 요소
$("input[name]").css("background-color", "red");

// name 속성의 값이 newmilk인 요소
$("input[name='newmilk']").val("newmilk");

// name 속성의 값에서 man이 포함되는 요소
// $("input[name*='man']").val("man이 포함된 요소");
  • a태그 예제
// title 어트리뷰트를 갖는 하이퍼 링크와 일치된다.
$("a[title]")

// href 값이 mailto로 시작하는 하이퍼 링크와 일치된다.
$('a[href^="mailto:"]')

// pdf 파일에 링크가 걸린 모든 하이퍼링크와 일치된다.
$('a[href$=".pdf"]')

// studyin.co.kr이라는 값이 포함되어 있는 모든 하이퍼 링크와 일치된다.
$('a[href*="studyin.co.kr"]')
  • 특정 데이터 속성을 가진 요소 선택하기
$("[data-myAttribute='myValue']")

 

컨텐츠 필터

  • :contains - 특정 텍스트가 들어가 있는 요소
$("p:contains(world)").css("color", "red");
  • :empty
$( "td:empty" )
  .text( "Was empty!" )
  .css( "background", "rgb(255,220,200)" );
  • :has(selector)
$("ul").has("li").addClass("full");
  • 숨겨진 요소와 표시된 요소 선택
// 숨겨진 모든 요소 선택하기
$(":hidden")

// 표시된 모든 요소 선택하기
$(":visible")
<ul>
    <li>0: hello world</li>
    <li>1: hello world</li>
    <li>2: hello world</li>
    <li>3: hello world</li>
    <li>4: hello world</li>
    <li style="display: none;">5: hello world</li>
    <li style="display: none;">6: hello world</li>
    <li style="display: none;">7: hello world</li>
    <li style="display: none;">8: hello world</li>
    <li style="display: none;">9: hello world</li>
  </ul>
$(function(){
	$("li:hidden").show();
	$("li:visible").css("color", "red");
})

 

jQuery 탐색

<div class="grandparent">
 grandparent
 <div class="parent">
  parent
  <div class="child">
   child
   <span class="subchild">subchild</span>
  </div>
 </div>
 <div class="surrogateParent1">surrogateParent1</div>
 <div class="surrogateParent2">surrogateParent2</div>
</div>
  • parent() : 바로 위 부모 엘리먼트 탐색
// div.child를 반환
$("span.subchild").parent();

// 주어진 선택자와 일치하는 모든 부모 선택
// div.parent 반환
$("span.subchild").parents("div.parent");

// 모든 부모 선택
// div.child, div.parent, div.grandparent 반환
$("span.subchild").parents();
  • closest() : 가장 가까운 조상 선택
// 가장 가까운 부모 선택. 단 하나의 부모만 선택하며, 초기 요소 자체도 검색 대상에 포함

// [div.child] 반환
$("span.subchild").closest("div");

// 셀렉터도 검색 대상에 포함되므로 [div.child]를 반환
$("div.child").closest("div");
  • children() : 바로 아래 자식 엘리먼트를 탐색
  • find() : 모든 하위 엘리먼트를 탐색
// 바로 아래 자식 엘리먼트 선택:
// [div.parent, div.surrogateParent1, div.surrogateParent2] 반환
$("div.grandparent").children("div");

// 선택한 요소 내에서 선택자와 일치하는 모든 요소 찾기:
// [div.child, div.parent, div.surrogateParent1, div.surrogateParent2] 반환
$("div.grandparent").find("div");
  • siblings() : 모든 형제 앨리먼트를 탐색
// 주어진 선택자와 일치하는 요소의 형제 요소를 양방향으로 선택:

// [ div.surrogateParent1, div.surrogateParent2 ] 반환
$("div.parent").siblings();

// [ div.parent, div.surrogateParent2 ] 반환
$("div.surrogateParent1").siblings();
  • next() : 다음 형제 엘리먼트를 탐색
  • prev() : 이전 형제 엘리먼트를 탐색
// 다음 형제 앨리먼트를 탐색
// [div.surrogateParent1] 반환
$("div.parent").next();

// Selecting a prev sibling of the selectors:
// div.parent 앞에 형제가 없으므로 [] 반환
$("div.parent").prev();

// Selecting all the next siblings of the selector:
// [div.surrogateParent1, div.surrogateParent2] 반환
$("div.parent").nextAll();

// [div.surrogateParent1] 반환
$("div.parent").nextAll().first();

// [div.surrogateParent2] 반환
$("div.parent").nextAll().last();

// 이전 형제 엘리먼트를 탐색
// [div.surrogateParent1, div.parent] 반환
$("div.surrogateParent2").prevAll();

// [div.surrogateParent1] 반환
$("div.surrogateParent2").prevAll().first();

// [div.parent] 반환
$("div.surrogateParent2").prevAll().last();

 

each

each() 메서드로 반복문을 사용할 수 있다.

$(function () {
 $("td").each(function () {
  const origianl_content = $(this).html();
  $(this).html("-" + origianl_content + "-");
  });
});

 

attr & value

attr() 메서드로 엘리먼트의 속성값을 읽거나 쓸 수 있다.

<div>
 <a href="https://www.naver.com" target="_blank">네이버</a>
 <a href="https://www.daum.net" target="_blank">다음</a>
 <a href="https://www.google.com" target="_blank">구글</a>
</div>
<div>
 <div>
  <label>id</label>
  <input type="text" name="id" value="120" />
 </div>
 <div>
  <label>username</label>
  <input type="text" name="username" value="peter" />
 </div>
</div>
  • 속성 읽기
$("a").attr("href");

$("a").length;

$("a").each(function(){
 $(this).attr("href");
});
  • 속성 쓰기
$("a").attr("href", "allMyHrefsAreTheSameNow.html");
 
$("a").attr({
 title: "all titles are the same too!",
 href: "somethingNew.html"
});
  • 값 읽기
$("input[name='id']").val();
  • 값 쓰기
$("input[name='id']").val('220');

 

class, css 설정

<table id="language">
 <thead>
  <tr>
   <th>언어</th>
   <th>종류</th>
   <th>연도</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td id="td-java" data-language="java">Java</td>
   <td>정적언어</td>
   <td>1995</td>
  </tr>
  <tr>
   <td id="td-ruby" data-language="ruby">Ruby</td>
   <td>동적언어</td>
   <td>1993</td>
  </tr>
  <tr>
   <td id="td-smalltalk" data-language="smalltalk">Smalltalk</td>
   <td>동적언어</td>
   <td>1972</td>
  </tr>
  <tr>
   <td id="td-c++" data-language="c++">C++</td>
   <td>정적언어</td>
   <td>1983</td>
  </tr>
 </tbody>
</table>

 

css() : 엘리먼트의 css 값 읽기, 쓰기, 변경

  • 폰트 사이즈 읽고 쓰기
$java = $("#td-java");
console.log($java.css("font-size"));
$java.css("font-size", "30px");
console.log($java.css("font-size"));
  • padding 변경
$("td").css("padding", "1rem");

 

clsss 추가, 제거 및 토글

  • addClass - class 추가
$("#td-ruby").addClass("highlight");
  • removeClass - class 제거
$("#td-ruby").removeClass("highlight");
$(".title").removeClass("title");
  • hasClass - class 보유 여부
$("#td-ruby").hasClass("highlight");
$("#td-ruby").addClass("highlight");
$("#td-ruby").hasClass("highlight");
  • toggleClass - class 토글
$("#td-ruby").toggleClass("highlight");

 

클릭 이벤트

$(function() {
  $("#btn1").on("click", function() {
    $target = $("#language thead");
    if ($target.hasClass("highlight")) {
      $target.removeClass("highlight");
    } else {
      $target.addClass("highlight");
    }
  });
});

 

엘리먼트 조작

<div id="row1" class="row">
 <div id="item1" class="item">1</div>
 <div id="item2" class="item">2</div>
 <div id="item3" class="item">3</div>
 <div id="item4" class="item">4</div>
 <div id="item5" class="item">5</div>
</div>
<div id="row2" class="row">
 <div id="item6" class="item"><button>6</button></div>
 <div id="item7" class="item"><button>7</button></div>
 <div id="item8" class="item"><button>8</button></div>
 <div id="item9" class="item"><button>9</button></div>
 <div id="item10" class="item"><button>10</button></div>
</div>
<div id="row3" class="row">
 <div id="item11" class="item">11</div>
 <div id="item12" class="item">12</div>
 <div id="item13" class="item">13</div>
 <div id="item14" class="item">14</div>
 <div id="item15" class="item">15</div>
</div>
  • html() - 요소의 내용 html 읽기
$("#item2").html(); // '2'
$("#item6").html(); // '<button>6</button>'
  • html(값) - 요소의 html 쓰기
$("#item2").html("2222");
$("#item2").html("naver");
  • text() - 요소의 text 읽기
$("#item2").text(); // '2'

$("#item6").text(); // '6'
  • text(값) - 요소의 text 쓰기
$("#item2").text("2222");
$("#item2").text("naver");
$("#item6").text("6666");
  • append() - 요소 추가하기
$(".row").append("<button>new button</button>");
$("#item11").append("<button>new button</button>");
$("#item15").append($("#item6"));
  • appendTo() - 특정 위치 요소 추가 하기
$("<button>new button</button>").appendTo(".row");
$("<button>new button</button>").appendTo("#item11");
$(".row:first").appendTo(".row:last");
$(".row:first .item").appendTo(".row:last");
  • clone() - 복사하기
$copyItem = $("#item1").clone();
$(".row:last").append($copyItem);
$("#item1").clone().appendTo(".row:last");
  • prepend() - 선택한 요소의 하위중 앞에 콘텐츠를 추가
$("#item2").prepend("hello");
  • prependTo() - 해당요소를 특정 위치에 앞에 추가
$("<button>hello</button>").prependTo("#item2");
  • after() - 특정요소 뒤에 추가하기
$("#row1").after("<p>hello world</p>");
  • before() - 특정요소 앞에 추가하기
$("#row1").before("<p>hello world</p>");

 

effect

메소드 설명 사용예제
.hide() 선택한 요소를 사라지게 한다. $("#item1").hide();
.show() 선택한 요소를 나타나게 한다. $(".item").show();
.toggle() 표시와 숨김을 번갈아 실행한다. $("#row3").toggle();
.fadeOut() 천천히 사라진다. $("#row3").fadeOut();
.fadeIn() 천천히 나타난다. $("#row3").fadeIn();
.fadeToggle() fadeIn, fadeOut을 번갈아 실행한다. $("#row3").fadeToggle();
.fadeIn(time) 특정 시간에 걸쳐서 천천시 나타난다. $("#row3").fadeOut(3000);
$("#row3").fadeIn(3000);
$("#row2").fadeToggle('slow');
$("#row2").fadeToggle('fast');

회고

jQuery의 다양한 문법을 배웠다. jQuery를 잘 활용하기 위함이 아닌, 현업에 투입 되었을때 아직 남아있을 수도 있는 jQuery 코드를 읽을 수 있는 능력을 갖추기 위해 진행된 부분이라 내용을 깊게 다루진 않았다. 논리적인 지식보다는 단순 문법이라 어렴풋이 기억하고 있다가 필요할 때가 되면 다시 이 게시글을 찾아야겠다.

CSS Sprite 기법

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

CSS Sprites Generator Tool | Toptal®

CSS Sprites Generator Upload your images. (Note: Please don’t upload HUGE files. That’s not the purpose of sprites technique.)

www.toptal.com

  • CSS Sprites Generator 에서 이미지를 합친 후, 위치를 지정하여 표시한다.
.bg-icon_check_empty {
    width: 22px; height: 22px;
		// 아래 부분만 복사해서 속성값을 변경하면 사용 가능하다.
    background: url('css_sprites.png') -11px -81px;
}
  • 가장 상위 요소에 이미지를 넣고, 각각의 요소에는 위치값만 넣는 방법도 있다. → 더 좋은듯!
[class^="icon"]::before {
	background-image: url('images.png');
}

.icon-google::before {
    background-position: -99px -81px ;
}

.icon-naver::before {
    background-position: -187px -81px ;
}

기존의 방식보다 이미지를 빠르게 로딩할 수 있다.

  • 단점
    • 중간에 있는 한가지 요소가 바뀌면, 계속해서 추가해야하고.. 공간 낭비가 된다.
    • 이미지 용량을 줄이려고 사용하는데 불필요한 요소가 누적되어서 용량이 커지는 상황이 발생..!
    • 포토샵이나 피그마를 활용하여 직접 이미지를 편집하게 될 것이다.. Sprites Generator는 순서도 정할 수 없고 한계가 있다.

 

레티나 디스플레이 대응법

  • 레티나: 특정한 시야 거리에서 인간의 눈으로는 화소를 구분할 수 없는 화소 밀도(300 PPI가 넘을 경우)를 가진 애플 LCD 제품의 브랜드 이름
  • 원인
    • 논리픽셀(css에서 표현하는 화소의 기본 단위)과 물리픽셀(디바이스가 실제로 처리할 수 있는 화소의 기본 단위)의 차이가 발생
    • 브라우저는 css에서 정의한 픽셀만큼 이미지를 렌더링 해야하기 때문에 원래는 물리픽셀에 맞게 렌더링된 이미지가 논리픽셀 만큼 커져버리게 된다.
  • 해결방법
    • 그리고자 하는 원본 사이즈의 가로 세로 2배 되는 이미지를 준비
    • 사이트에서 이미지를 합칠때, 간격도 2배로 해서 계산되기 편하게 한다.
    /* 이미지가 1/4로 줄어들기 때문에 이미지 자체 사이즈를 줄여줘야한다. */
    background-image: url("images_login/css_sprites_x2.png");
    background-size: 123px 89px;
    
    /* 요소 배경이미지 위치값도 다 1/2로 수정한다. */
    .icon-google::before {
        /*background-position: -20px -20px ;*/
        background-position: -10px -10px ;
    }
    .icon-naver::before {
        /*background-position: -116px -20px ;*/
        background-position: -58px -10px ;
    }
    
    • 디자이너분께 이미지를 2배로 달라고 한다..
    /* 기존에는 아래와 같이 픽셀이 2배인 것에 미디어쿼리를 적용했다. */
    @media screen and (-webkit-device-pixel-ratio: 2) {
    	/* code */
    }
    

 

반응형 컨텐츠 만들기 - img

  • 이미지 포맷
    • GIF, JPG/JPEG, PNG, SVG, WebP, AVIF
  • 이미지 반응형 만들기
    • 뷰포트가 넓어지거나 줄어들 때 !
/* 단위를 vw로 하면 부모요소가 있을때 문제가 생김*/
img {
	width: 100%;
}

/* 이미지가 줄어들긴 하지만 기존 이미지보다 늘어나지 않는다. */
img {
	max-width: 100%;
}
  • 백그라운드 이미지 반응형 만들기
<style>
	article {
		width: 100vw;
		height: 100vh;
		background: url(logo_google.jpeg) black center/contain no-repeat;
}
</style>
<body>
	<article> </article>
</body>

 

반응형 컨텐츠 만들기 - video, iframe

  • 동영상 포맷
 

Media container formats (file types) - Web media technologies | MDN

The format of audio and video media files is defined in two parts (three if a file has both audio and video in it, of course): the audio and/or video codecs used and the media container format (or file type) used. In this guide, we'll look at the container

developer.mozilla.org

  • video 속성
    • preload =“none”, “auto”; : 페이지를 로드할때 영상을 미리 로드할지 말지 결정합니다.
    • poster : 비디오를 내려받을 동안 혹은 영상을 재생할때까지 표시할 이미지를 지정합니다.
    • controls : 브라우저가 재생에 핋요한 컨트롤러를 제공할지 지정합니다.
    • autoplay:  파일이 다운로드가 완료되면 자동으로 재생될지 지정하는 속성입니다.
    • muted: 소리를 끕니다.
    • loop : 비디오가 끝나고 반복적으로 재생할지 지정합니다.
  • video 반응형 만들기
video {
	width: 100%;
}

video {
	max-width: 100%
}
  • iframe 반응형 만들기
.cont-video {
	position: relative;
	padding-top: 56.25%;
	/* 16:9 비율 : aspect-ratio 사용 가능하나 지원 브라우저가 별로 없다. 최신기술! */
	/* 많은 개발자들이 잘 모르는 CSS 매직을 알려드리겠습니다 :) */
	/* padding-top, padding-bottom 속성의 % 값은 부모 요소의 넓이에 비례합니다. */
	/* 예를 들어 부모의 넚이가 1200px 이라면 자식요소의 padding-top=50% 의 값은 600px 과 같습니다. */
} 

.video-next-level {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}
  • 반응형 video background 만들기
.full-screen-vid {
	position: fixed;
	top: 50%;
	left: 50%;
	min-height: 100%;
	transform: translate(-50%, -50%);
	/* pointer-events: none; */
}

회고

오랜만에 돌아온 CSS 수업! JS 하다가 들으니까 사막의 오아시스 같다... 기본 문법 학습이나 실습을 하며 어느정도 웹을 만들어낼수는 있지만, 아직 웹접근성이라던지 최적화, 반응형을 만드는거에 약하다는 생각이 들었는데 이렇게 다시 실무에서 활용할 수 있는 좋은 기술들을 알 수 있어서 좋았다.

레티나 디스플레이는 처음 듣는 단어였는데 이런것까지 신경써야 한다니 아직 갈길이 멀은것 같다. 수업시간에 예시로 네이버 쇼핑 페이지에 들어갔는데 레티나 디스플레이 대응이 안되어 있어 맥북을 사용하는 나의 화면에는 이미지가 살짝 깨져보였다ㅎ 네이버 같은 대기업도 안맞춰논게 있다니.. 까볼수록 신기한 세계다ㅋㅋㅋ 시간이 난다면 초반에 진행했던 과제들을 개선하며 다시 만들어보는 시간을 가져봐야겠다!

+ Recent posts