사이트명 : 안다르 모바일
작업기간 : 3일
라이브러리 : swiper, jQuery
유형 : 모바일 적응형,클론코딩
svg
란?SVG(Scalable Vector Graphics)는 '벡터 그래픽'을 표현하기 위한 XML기반의 포맷이다.
JPEG, PNG 등 픽셀 기반 이미지와 다르게 SVG는 '읽을 수 있는 코드'이므로 정보 접근성이 좋고, 코드 수정을 통해 이미지를 수정할 수 있다.
1. img
태그
<img src="nana.svg" />
2.background-image
.nana {
width: 300px;
height: 120px;
outline: 2px solid red;
background-image: url("./potion.svg");
}
이미지로 background-image
로 넣어도 되지만 Data URI로 변경해서 넣어도 무방하다
Data URI은 data:
스킴으로 시작되는 URL로, 작은 파일을 인라인으로 임베드할 수 있다.
이렇게 임베드된 데이터에는 HTTP 요청 및 헤더 트래픽이 필요하지않다.
SVG 코드를 바로 Data URI로 바꿔주는 URL-encoder for SVG를 통해 URI 값을 얻을 수 있다.
위의 두가지 방법(
img
태그와background-image
) 은 CSS로 SVG 내부를 제어할 수가 없다.
3. inline code
<a href="" role="button" class="menu" aria-label="메뉴">
<svg width='20' height='17' viewBox='0 0 20 17' fill='#fff' xmlns='http://www.w3.org/2000/svg'><path fill-rule='evenodd' clip-rule='evenodd' d='M20 0.5H0V2H20V0.5ZM20 7.75H0V9.25H20V7.75ZM0 15H16V16.5H0V15Z' fill='#fff'/></svg>
</a>
HTML 상에 코드를 그대로 넣어주는 방법이다.
장점은 이미지 로드가 필요없다.
단점은 HTML 코드의 가독성이 좋지않고 캐싱이 불가능하다.
캐싱(Caching)이란?
Caching == Cache + ing
Cache : 자주 필요한 데이터나 값의 복사본을 일시적으로 저장, 보관하기 위해 사용하는 곳
Cacheing : cache를 사용하는 것
4. object
<object type="image/svg+xml" data="./potion.svg" class="nana"></object>
캐싱이 되지만 외부 CSS기능을 쓸 수 없다.
즉, object에 대한 스타일링은 가능하지만, svg 내부 코드는 조작할 수 없다.
이를 해결하기 위해 svg 파일 자체에 style
을 추가할 수 있지만 기존 svg의 스타일 변경이 불가능하다.
<svg>
<style>
.potion1 {
fill: #ffeb3b;
}
</style>
<path class="potion1" d="....."/>
</svg>
기존 svg의 스타일을 변경하려면 스타일시트를 따로 만들고 svg파일내에 외부 css경로 링크를 불러온다. 그 후 style.css에서 원하는 스타일로 변경한다.
이 방식은 캐싱이 되고, HTML이 깔끔해지며, SVG 코드 조작이 가능하다는 장점이 있지만 스타일시트를 한 번 더 연결해야하고, 링크가 안 걸린다는 단점이 있다.
object
를 a
태그로 감싸도 링크가 안 걸리기때문에 svg 코드 내에 a
를 넣어줘야한다.
SVG에 기능 및 효과를 주지않고 이미지로써 활용하려면
img
또는background-image
로 활용해도 문제없다. 그 외에는 html에 바로 코드를 입력하는 형식이나object
를 이용하는게 활용도가 좋다.
기존 안다르 홈페이지의 경우 헤더내의 아이콘이 스크롤 시 색상이 변경되야하는 기능을 추가해야하는데 svg
를 background-image
로 이용하여 불필요한 코드를 작성하게 되었다.
markup
css
.gnb .group-gnb.show svg path{
fill:#000
}
이런 문제점을 고치기 위하여 html
에 바로 svg
를 마크업 해주고 css
를 이용해 헤더내의 svg
의 컬러를 변경하였다.
jQuery
let lastScroll = 0;
$(window).scroll(function(){
const usrScroll = $(this).scrollTop();
if (usrScroll > 0) {
$('.gnb, .group-gnb, .group-category').addClass('show')
} else {
$('.gnb, .group-gnb, .group-category').removeClass('show')
}
lastScroll = usrScroll;
})
$(window).trigger('scroll');
현재 스크롤 값을 변수로 넣고 0보다 값이 클때 show
클래스가 추가되도록 구현했다.
이때 새로고침시에는 헤더가 사라져버려서 강제로 스크롤 이벤트를 한번 시행하게하는 .trigger()
함수를 추가로 넣어줬다.
css
.header .group-category .category-list{
display: flex;
gap: 15px;
width: calc(100% - 30px);
overflow-x: auto;
-ms-overflow-style: none;
scrollbar-width: none;
}
.header .group-category .category-list::-webkit-scrollbar {
display: none;
}
메뉴가 많아질 경우를 대비해 모바일에서 메뉴가 스크롤 될 수 있도록 조치하였다.
jQuery
$('.header .btn-open').click(function(e){
e.preventDefault();
if ($(this).hasClass('on')) {
$('.category-item').css('display','block')
$('.category-active').css('display','none')
$(this).removeClass('on').attr('aria-label','펼쳐보기')
$('.sort-list').stop().slideUp()
} else {
$('.category-item').css('display','none')
$('.category-active').css('display','block')
$(this).addClass('on').attr('aria-label','닫기')
$('.sort-list').stop().slideDown()
}
})
.hasClass('on')
함수로 조건문을 이용하여 구현하였다.
css
.header .menu-bg{
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
position: fixed;
top: 0;
left: 0;
z-index: 10;
display: none;
}
.header .menu-bg.on{
display: block;
}
.header .menu-con{
position: fixed;
top: 0;
left: -100%;
}
.header .menu-con.on{
left: 0;
}
jQuery
$('.header .menu').click(function(e){
e.preventDefault();
$('.header .menu-con, .menu-bg').addClass('on')
$('body').addClass('notScroll')
})
$('.header .btn-close,.menu-bg').click(function(e){
e.preventDefault();
$('.header .menu-con, .menu-bg').removeClass('on')
$('body').removeClass('notScroll')
})
메뉴태그는 left: -100%
으로 안보이게 위치해 둔 후 클래스on
상태가 되면 나타나도록 처리해둔다.
메뉴가 나타나고 뒤에 검은배경 처리해줄 태그를 미리 만들어둔 후, 클릭전에는 안보이게 display:none
상태로 둔다.
메뉴 외에 다른 부분이 스크롤 되는 걸 막기위해 body
에 아래와 같은 클래스를 만들어 추가될 수 있도록 한다.
.notScroll{
overflow: hidden;
width: 100%;
height: 100vh;
}
jQuery
$('.group-menu .nav').click(function(e){
const thisSubBox = $(this).siblings('.nav-list');
if(thisSubBox.length > 0){
e.preventDefault();
thisSubBox.slideToggle();
$(this).toggleClass('on');
}
if($('.group-menu .nav').hasClass('on')){
$(this).attr('aria-label','접기')
}else{
$(this).attr('aria-label','펼치기')
}
})
해당메뉴의 자식태그를 변수로 두고 하나라도 있을 경우, 클릭시마다 열릴 수 있도록 .toggleClass()
함수를 이용했다.