카테고리 보관물: HTML/CSS

Sass에서 다크모드 적용하기

점점 다크모드를 적용하는 사이트들이 늘어나고 있는데, Sass를 사용하여 다크모드를 쉽게 적용할 수 있게 코드를 만들어 봤습니다.

우선 일반 컬러 테마와 다크모드 테마를 $light-theme와 $dark-theme 맵에 각각 선언합니다. (4-13줄)
그리고 위의 맵을 사용해서 CSS에서 var()를 사용하기 위한 변수를 선언하고, 미디어쿼리도 적용해 줍니다. (15-25줄)
그러면 CSS의 1-13줄과 같이 변수가 생성됩니다.

이제 본격적으로 믹스인을 생성합니다. (28-41줄)
기본적으로 color-theme(key: value)의 형태로 한 개 이상의 키:밸류 쌍으로 된 속성을 전달할 수 있습니다. 그러나 border나 background 등과 같이 색상 이외에 다른 속성도 같이 설정할 필요가 있는 경우에 color, prefix, suffix의 속성을 가진 맵을 사용할 수 있습니다.

43-53줄과 같이 믹스인을 사용하면 CSS의 14-29줄에 해당하는 코드를 생성합니다.
같은 속성이 두 개씩 만들어 지는 것은 CSS의 변수나 미디어쿼리를 지원하지 않는 구형 브라우저에서는 첫 번째 속성의 컬러를 사용하고, 지원하는 브라우저는 변수와 미디어쿼리가 적용되도록 하기 위해서 입니다.
IE와 같은 구형 브라우저를 지원할 필요가 없다면 31, 37줄의 코드는 삭제하면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
@use "sass:map";
@use "sass:meta";
 
$light-theme: (
    bgc: #fff,
    txt: #333,
    brd: #ff6
);
$dark-theme: (
    bgc: #333,
    txt: #eee,
    brd: #339
);
 
:root{
    @each $k, $v in $light-theme{
        #{"--" + $k}: #{$v};
    }
}
@media (prefers-color-scheme: dark){
    :root{
        @each $k, $v in $dark-theme{
            #{"--" + $k}: #{$v};
        }
    }
}
 
@mixin color-theme($args...){
    @each $k, $v in meta.keywords($args){
        @if(meta.type-of($v) == "string"){
            #{$k}: map.get($light-theme, $v);
            #{$k}: #{"var(--" + $v + ")"};
        }@else if(meta.type-of($v) == "map"){
            $c: map.get($v, color);
            $p: map.get($v, prefix);
            $s: map.get($v, suffix);
            #{$k}: $p map.get($light-theme, $c) $s;
            #{$k}: $p #{"var(--" + $c + ")"} $s;
        }
    }
}
 
html, body{
	@include color-theme($color: txt, $background-color: bgc);
}
 
.border{
	@include color-theme($border: (prefix: 1px solid, color: brd));
}
 
.background{
    @include color-theme($background: (color: bgc, suffix: url(bg.jpg) no-repeat 50% 50%));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
:root {
  --bgc:#fff;
  --txt:#333;
  --brd:#ff6;
}
 
@media (prefers-color-scheme: dark) {
  :root {
    --bgc:#333;
    --txt:#eee;
    --brd:#339;
  }
}
html, body {
  color: #333;
  color: var(--txt);
  background-color: #fff;
  background-color: var(--bgc);
}
 
.border {
  border: 1px solid #ff6;
  border: 1px solid var(--brd);
}
 
.background {
  background: #fff url(bg.jpg) no-repeat 50% 50%;
  background: var(--bgc) url(bg.jpg) no-repeat 50% 50%;
}

크롬에서 opacity transition 사용할 때 레이어가 사라지는 문제

지금 진행하고 있는 프로젝트에서, 화면 하단에 고정된 레이어를 만들고, 경우에 따라 화면 아래로 사라졌다 나타나는 효과를 적용하였습니다.

1
2
3
.fixed_button_wrap{position:fixed;left:0;bottom:0;width:100%;height:45px;opacity:1;
    transition:bottom 0.3s, opacity 0.3s;}
.fixed_button_wrap.hide{pointer-events:none;bottom:-50px;opacity:0;}

테스트한 단말과 브라우저들에서는 모두 정상적으로 표시되었으나, 일부 안드로이드(크롬)에서 한 번 사라진 레이어가 다시 나타나지 않는 문제가 발견되었습니다. 디버깅 해보면 좌표와 투명도는 모두 정상으로 나타나지만, 화면에는 보이지 않더군요.
해결책은 -webkit-backface-visibility:hidden;를 추가해 주어야 합니다.

1
2
3
.fixed_button_wrap{position:fixed;left:0;bottom:0;width:100%;height:45px;opacity:1;
    transition:bottom 0.3s, opacity 0.3s;-webkit-backface-visibility:hidden;}
.fixed_button_wrap.hide{pointer-events:none;bottom:-50px;opacity:0;}

flex를 사용한 탭 만들기 2

flex를 사용한 탭 만들기에서 간단한 탭 만드는 방법을 알아봤습니다. 그런데 스마트폰에서 볼때는 의도한 데로 표시되지 않는 것을 볼 수 있습니다. 이는 모바일 브라우저에서 인식하는 스타일이 다르기 때문으로, 다음과 같이 -webkit- 접두어를 추가해 주면 됩니다.

1
2
3
4
5
6
7
8
.container{
    display: -webkit-flex;/* for mobile */
    display: flex;
}
.container .child{
    -webkit-flex:auto;/* for mobile */
    flex:auto;
}

이제 스마트폰에서도 대부분의 경우에는 원하는 결과를 얻을 수 있습니다. 그러나 우리의 기대를 저버리지 않는 갤레기 일부 갤럭시 시리즈에서는 제대로 동작하지 않습니다. 이런 일부 스마트폰을 위해서는 다음과 같이 두 줄의 코드를 더 추가해야 합니다.

1
2
3
4
5
6
7
8
9
10
.container{
    display:-webkit-box;/* for galaxy */
    display: -webkit-flex;/* for mobile */
    display: flex;
}
.container .child{
    -webkit-flex:auto;/* for mobile */
    flex:auto;
    width:33.3%;/* for galaxy */
}

여기서 병맛인건, width값은 탭의 갯수에 따라서 1/n 값으로 적용해야 한다는 점입니다. 예를 들어 2개이면 50%, 4개이면 25% 처럼 말이죠.

그래서 대안으로 자바스크립트를 사용해서 리스트의 갯수에 따라서 width 값을 입력해 주는 스크립트를 사용할 수 있습니다.

1
2
3
4
$(function(){
    var lis = $("ul.flex_container > li");
    lis.width((100 / lis.length) + "%");
});

이제 모바일에서도 원하는 결과를 얻을 수 있습니다.

  • 111
  • 222
  • 333

flex를 사용한 탭 만들기

폭이 가변으로 조종되는 메뉴나 탭을 만들 때 flex를 사용해면 쉽게 처리가 가능합니다.
탭을 포함하는 콘테이너에 display:flex를 적용하고, 콘테이너에 들어가는 요소는 flex:auto를 주면… 끝!!! HTML과 CSS 코드는 다음과 같습니다.
(box-shadow는 영역을 눈으로 확인하기 위해 사용하였고, 실제 코드상 필요없는 부분입니다.)

1
2
.container{display:flex;}
.container .child{flex:auto;box-shadow:0 0 1px 1px #69f;}
1
2
3
4
<div class="container">
    <div class="child">111</div>
    <div class="child">222</div>
</div>

그러면 다음과 같은 결과를 얻을 수 있죠.

111
222

.
flex를 사용한 탭 만들기 더보기

페이지 리프레시 없이 CSS만 리로드하기

웹페이지 개발할 때 CSS 수정하고 확인을 위해서 수시로 페이지 리프레시를 하다보면 무척 귀찮습니다. 더욱이 AJAX를 사용하는 경우에는, 작업중인 화면을 보기 위해 여러 번 클릭을 해서 들어가야 하는 번거로움도 있고요.
이럴 때 편하게 페이지 리프레시 없이 CSS만 다시 불러올 수 있는 방법을 소개합니다.

파이어폭스의 부가기능(도구 > 부가기능) 메뉴로 들어가서, “CSS”로 검색을 해보면 다양한 플러그-인 들을 찾을 수 있습니다.
css reloader search result

이 중에서 마음에 드는 녀석을 골라서 사용하면 되겠습니다.
물론 크롬에도 비슷한 부가기능 들을 쉽게 찾을 수 있습니다.

그런데, 이미 Web Developer Toolbar를 사용하고 있다면, 굳이 새로운 플러그-인을 설치할 필요가 없습니다.
웹 디벨로퍼 툴바에서 CSS > Reload Likned Style Sheets 메뉴를 실행하면, 페이지를 새로고침하지 않고 CSS 파일만 새로 불러와서 수정된 내용을 바로 확인 할 수 있습니다.

그러나 매번 두 번씩 클릭을 해야하는 것이 여간 불편한 것이 아닙니다. 이 점에 대해서도 대비책이 있는데, 그것은 바로 단축키를 지정하는 것입니다.
페이지 리프레시 없이 CSS만 리로드하기 더보기