z-index

z-index 속성은 요소의 쌓는 순서를 설정한다.

z-index는 position 속성이 설정된 요소, flex의 직접적인 자식 요소에서만 동작한다.

예를들어, position: absolute, position: relative, position: fixed, or position: sticky 그리고 display: flex가 설정된 요소의 직접적인 자식 요소

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
.container {
position: relative;
}

.black-box {
position: relative;
z-index: 1;
border: 2px solid black;
height: 100px;
margin: 30px;
}

.gray-box {
position: absolute;
z-index: 3; /* gray box will be above both green and black box */
background: lightgray;
height: 60px;
width: 70%;
left: 50px;
top: 50px;
}

.green-box {
position: absolute;
z-index: 2; /* green box will be above black box */
background: lightgreen;
width: 35%;
left: 270px;
top: -15px;
height: 100px;
}

z-index

만약 z-index 설정없이 두 요소가 오버랩되어 있다면, HTML 코드가 나중에 정의된 요소가 제일 위에 보여진다.

댓글 공유

Position

position 속성은 요소에 사용된 포지셔닝 방법을 설정한다.

  • static
  • relative
  • fixed
  • absolute
  • sticky

position: static;

HTML 요소는 static 속성이 기본값으로 되어있다.

static 속성은 top, bottom, left, right 속성에 영향을 받지 않는다.

positioin: relative;

relative 속성은 원래 위치의 상대으로 배치되는 속성이다.

relative 속성이 설정된 요소의 top, right, bottom, left 속성을 설정하는 것은 원래 위치로부터 조정될 수 있을 것이다.

다른 컨텐츠는 요소가 남긴 간격에 맞게 조정되지 않는다. 마치 relative 속성이 설정된 요소가 붕 띄워진 것 처럼 작동한다.

1
2
3
4
5
div.relative {
position: relative;
left: 30px;
border: 3px solid #73ad21;
}

position: fixed;

fixed 속성이 설정된 요소는 viewport에 상대적으로 위치한다.

이것은 page가 스크롤되더라도 항상 같은 위치에 머물러 있다는 것을 의미한다.

top,left,bottom,right 속성으로 요소의 위치를 조정할 수 있다.

1
2
3
4
5
6
7
div.fixed {
position: fixed;
bottom: 0;
right: 0;
width: 300px;
border: 3px solid #73ad21;
}

position:absolute;

absolute 속성이 설정된 요소는 fixed 같이 viewport에 상대적인 위치를 갖는 것 대신, relative 속성을 가진 가장 가까운 부모 요소를 기준으로 위치한다.

부모 요소에 relative 속성이 없더라도, absolute 속성을 가진 요소는 document body를 기준으로 움직인다.

absolute 속성을 가진 요소는 기존 flow에서 제거되어 요소들에게 오버랩 될 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
div.relative {
position: relative;
width: 400px;
height: 200px;
border: 3px solid #73ad21;
}

div.absolute {
position: absolute;
top: 80px;
right: 0;
width: 200px;
height: 100px;
border: 3px solid #73ad21;
}

absolute

position:sticky;

sticky 속성을 가진 요소는 사용자의 스크롤 위치를 기준으로 배치된다.

sticky 요소 스크롤 위치에 따라 relative와 fixed 속성을 왔다갔다 한다.

주어진 offset 위치가 viewport에서 충족되기 전까지는 relative로 배치된 다음, 조건이 충족되면 fixed로 고정된다.

댓글 공유

Display

diplay 속성은 레이아웃을 조작하는데 매우 중요한 속성이다.

대부분 요소의 기본값은 block 또는 inline이다.

Block-level 요소

block-level 요소는 새로운 줄에서 시작하고 가능한 최대 너비로 차지한다.

  • div
  • h1 ~ h6
  • p
  • form
  • header
  • footer
  • section

inline 요소

inline 요소는 필요한 만큼의 너비를 가지고 새로운 줄에서 시작하지 않는다.

  • span
  • a
  • img

display: none;

위 속성은 요소를 제거하고 다시 만드는 것 대신 요소를 숨기고 나타내기 위해 JavaScript와 함께 사용하는 속성이다.

script 요소는 display:none 속성이 기본값이다.

display:none과 visibility:hidden의 차이

display:none은 요소를 숨기고 페이지는 그곳에 해당 요소가 없는 것처럼 나타낸다.

하지만, visibility:hidden은 요소를 숨기지만 이전과 동일한 공간을 차지한다. 즉, 요소는 보이지 않지만 layout에는 영향을 미친다.

display:none과 visibility:hidden 비교

댓글 공유

List

list-style-type을 바꾸면 list item 마커를 변경할 수 있다.

추가로 list-style-image로 이미지를 삽입할 수도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ul.a {
list-style-type: circle;
}

ul.b {
list-style-type: square;
}

ol.c {
list-style-type: upper-roman;
}

ol.d {
list-style-type: lower-alpha;
}
ul {
list-style-image: url("sqpurple.gif");
}

list-style-position

list-item 마커를 list-item 내부 또는 외부로 위치를 이동시킬 수 있다.

1
2
3
4
5
6
7
ul.a {
list-style-position: outside;
}

ul.b {
list-style-position: inside;
}

기본 셋팅 제거하기

1
2
3
4
5
ul {
list-style-type: none;
margin: 0;
padding: 0;
}

댓글 공유

Link

Link는 CSS 속성으로 스타일링 할 수 있다. 추가로 상태까지 다르게 스타일링 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* unvisited link */
a:link {
color: red;
}

/* visited link */
a:visited {
color: green;
}

/* mouse over link */
a:hover {
color: hotpink;
}

/* selected link */
a:active {
color: blue;
}

❗️주의사항

  • a:hover는 무조건 a:link, a:visited 이후에 와야한다.
  • a:active는 무조건 a:hover 이후에 와야한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
a:link,
a:visited {
background-color: #f44336;
color: white;
padding: 14px 25px;
text-align: center;
text-decoration: none;
display: inline-block;
}

a:hover,
a:active {
background-color: red;
}

linkbutton

댓글 공유

Icons

HTML에 아이콘을 넣는 가장 쉬운 방법은 Font Awesome 같은 라이브러리를 사용하는 것이다.

icon 클래스 이름을 i 태그나 span 태그에 inline 형태로 추가하라.

라이브러리 속 모든 아이콘은 CSS(크기, 색상, 그림자 등)로 사용자 정의할 수 있는 확장 가능한 벡터이다.

아래 예시에서는 Font Awesome 라이브러리를 예시로 들었지만, Bootstrap Icons, Google Icons 비슷하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html>
<head>
<script
src="https://kit.fontawesome.com/a076d05399.js"
crossorigin="anonymous"
></script>
</head>
<body>
<i class="fas fa-cloud"></i>
<i class="fas fa-heart"></i>
<i class="fas fa-car"></i>
<i class="fas fa-file"></i>
<i class="fas fa-bars"></i>
</body>
</html>

icons

댓글 공유

문제

상근이는 어렸을 적에 “봄보니 (Bomboni)” 게임을 즐겨했다.

가장 처음에 N×N크기에 사탕을 채워 놓는다. 사탕의 색은 모두 같지 않을 수도 있다. 상근이는 사탕의 색이 다른 인접한 두 칸을 고른다. 그 다음 고른 칸에 들어있는 사탕을 서로 교환한다. 이제, 모두 같은 색으로 이루어져 있는 가장 긴 연속 부분(행 또는 열)을 고른 다음 그 사탕을 모두 먹는다.

사탕이 채워진 상태가 주어졌을 때, 상근이가 먹을 수 있는 사탕의 최대 개수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 보드의 크기 N이 주어진다. (3 ≤ N ≤ 50)

다음 N개 줄에는 보드에 채워져 있는 사탕의 색상이 주어진다. 빨간색은 C, 파란색은 P, 초록색은 Z, 노란색은 Y로 주어진다.

사탕의 색이 다른 인접한 두 칸이 존재하는 입력만 주어진다.

출력

첫째 줄에 상근이가 먹을 수 있는 사탕의 최대 개수를 출력한다.

예제 입력 1

1
2
3
4
3
CCP
CCP
PPC

예제 출력 1

1
3

예제 입력 2

1
2
3
4
5
4
PPPP
CYZY
CCPY
PPCC

예제 출력 2

1
4

예제 입력 3

1
2
3
4
5
6
5
YCPZY
CYZZP
CCPPP
YCYZC
CPPZZ

예제 출력 3

1
4

내 코드

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
54
55
56
57
58
59
60
61
62
63
64
const [n, ...input] = require("fs")
.readFileSync("/dev/stdin")
.toString()
.trim()
.split("\n");
const N = +n;
let candy = input.map((v) => v.split(""));

let max = 1;

for (let i = 0; i < N; i++) {
if (max == N) break;
for (let j = 0; j < N; j++) {
if (max == N) break;
candySwap(i, j);
}
}
console.log(max);

function candySwap(i, j) {
const dir = [
[0, 1],
[1, 0],
];
dir.forEach((v) => {
const [x, y] = v;

if (
i + x > -1 &&
j + y > -1 &&
i + x < N &&
j + y < N &&
candy[i + x][j + y] != candy[i][j]
) {
let temp = candy[i][j];
candy[i][j] = candy[i + x][j + y];
candy[i + x][j + y] = temp;
checkRow();
checkColumn();
candy[i + x][j + y] = candy[i][j];
candy[i][j] = temp;
}
});
}

function checkRow() {
for (let i = 0; i < N; i++) {
let checkArr = [1];
for (let j = 1; j < N; j++) {
checkArr[j] = candy[i][j - 1] == candy[i][j] ? checkArr[j - 1] + 1 : 1;
}
max = Math.max(...checkArr, max);
}
}

function checkColumn() {
for (let i = 0; i < N; i++) {
let checkArr = [1];
for (let j = 1; j < N; j++) {
checkArr[j] = candy[j - 1][i] == candy[j][i] ? checkArr[j - 1] + 1 : 1;
}
max = Math.max(...checkArr, max);
}
}

댓글 공유

문제

왕비를 피해 일곱 난쟁이들과 함께 평화롭게 생활하고 있던 백설공주에게 위기가 찾아왔다. 일과를 마치고 돌아온 난쟁이가 일곱 명이 아닌 아홉 명이었던 것이다.

아홉 명의 난쟁이는 모두 자신이 “백설 공주와 일곱 난쟁이”의 주인공이라고 주장했다. 뛰어난 수학적 직관력을 가지고 있던 백설공주는, 다행스럽게도 일곱 난쟁이의 키의 합이 100이 됨을 기억해 냈다.

아홉 난쟁이의 키가 주어졌을 때, 백설공주를 도와 일곱 난쟁이를 찾는 프로그램을 작성하시오.

입력

아홉 개의 줄에 걸쳐 난쟁이들의 키가 주어진다. 주어지는 키는 100을 넘지 않는 자연수이며, 아홉 난쟁이의 키는 모두 다르며, 가능한 정답이 여러 가지인 경우에는 아무거나 출력한다.

출력

일곱 난쟁이의 키를 오름차순으로 출력한다. 일곱 난쟁이를 찾을 수 없는 경우는 없다.

예제 입력 1

1
2
3
4
5
6
7
8
9
20
7
23
19
10
15
25
8
13

예제 출력 1

1
2
3
4
5
6
7
7
8
10
13
19
20
23

내 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const input = require("fs")
.readFileSync("/dev/stdin")
.toString()
.trim()
.split("\n")
.map(Number);

function getSevenSmalls(arr) {
let answer = [...arr];
let sum = arr.reduce((acc, cur) => acc + cur);
let diff = sum - 100;
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] + arr[j] === diff) {
answer.splice(j, 1);
answer.splice(i, 1);
return answer.sort((a, b) => a - b).join("\n");
}
}
}
}

console.log(getSevenSmalls(input));

해설

난쟁이 키의 합이 100이므로 9명의 키 합을 구한 뒤 2중 for문을 돌면서 나머지 2명의 키의 합이 차이와 같을 때, 2명을 제거한 배열을 반환하였다.
function getMaxCandies(board) {
const dx = [0, 1, 0, -1];
const dy = [1, 0, -1, 0];
let maxCandies = 1;

for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
for (let k = 0; k < 4; k++) {
const nx = i + dx[k];
const ny = j + dy[k];

    if (nx < 0 || ny < 0 || nx >= n || ny >= n) {
      continue;
    }

    const temp = board[i][j];
    board[i][j] = board[nx][ny];
    board[nx][ny] = temp;

    for (let l = 0; l < n; l++) {
      let rowCandies = 1;
      let colCandies = 1;

      for (let m = 1; m < n; m++) {
        if (board[l][m] === board[l][m - 1]) {
          rowCandies++;
        } else {
          maxCandies = Math.max(maxCandies, rowCandies);
          rowCandies = 1;
        }

        if (board[m][l] === board[m - 1][l]) {
          colCandies++;
        } else {
          maxCandies = Math.max(maxCandies, colCandies);
          colCandies = 1;
        }
      }

      maxCandies = Math.max(maxCandies, rowCandies, colCandies);
    }

    const temp2 = board[i][j];
    board[i][j] = board[nx][ny];
    board[nx][ny] = temp2;
  }
}

}

return maxCandies;
}

console.log(getMaxCandies(board));

댓글 공유

text

CSS는 많은 텍스트 속성을 가지고 있다.

❗️ 여기서 중요한 것은 text의 색상과 배경색의 대비이다. 이는 시각적인 문제에 있어 매우 중요하므로 대비를 고려하여 스타일링 해야한다.

text-alignment

text-align

text-align 속성은 text의 가로 정렬을 위해 사용된다.

1
2
3
p {
text-align: center; // 가운데 정렬
}

vertical-align

vertical-align 속성은 요소의 세로 정렬을 위해 사용된다.

1
2
3
img {
vertical-align: text-top; // 텍스트 기준보다 위쪽으로 이미지요소 배치
}

text-decoration

text-decoration 속성은 text에 라인을 추가한다.

❗️ 다만, underline 속성은 a 태그와 헷갈릴 수 있으니 유의하도록 하자.

Tip

a 태그는 기본값으로 underline 속성이다. 이것을 제거하고 싶다면 다음과 같이 한다.

1
2
3
a {
text-decoration: none;
}

text-transform

텍스트의 소문자, 대문자를 지정할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
p.uppercase {
text-transform: uppercase;
}

p.lowercase {
text-transform: lowercase;
}

p.capitalize {
text-transform: capitalize;
}

text-spacing

text-indent

첫줄의 들여쓰기 너비를 지정하는 속성이다.

1
2
3
p {
text-indent: 50px;
}

letter-spacing

글자 간격을 설정하는 속성이다.

1
2
3
4
5
6
7
h1 {
letter-spacing: 5px;
}

h2 {
letter-spacing: -2px;
}

line-height

라인 사이의 공백을 설정하는데 사용된다.

1
2
3
4
5
6
7
p.small {
line-height: 0.8;
}

p.big {
line-height: 1.8;
}

text-shadow

글자의 그림자를 설정하는 속성이다.

1
2
3
h1 {
text-shadow: 2px 2px 5px red;
}

첫번째부터 가로길이, 세로길이, blur, 색상이다.

shadow

1
2
3
4
h1 {
color: white;
text-shadow: 1px 1px 2px black, 0 0 25px blue, 0 0 5px darkblue;
}

여러가지 그림자를 설정할 수도 있다.

font

🔥 font 선택은 매우 중요하다!

왜냐하면 폰트를 적절히 선택하면, 웹사이트 브랜드와 가독성에 큰 영향을 줄 수 있기 때문이다.

computer 화면에서는 sans-serif 폰트가 serif 폰트보다 더 가독성이 좋다.

font-family

font-family 속성의 이름이 한 단어 이상이면, 따옴표로 감싸줘야한다.

1
2
3
4
5
6
7
8
9
10
11
.p1 {
font-family: "Times New Roman", Times, serif;
}

.p2 {
font-family: Arial, Helvetica, sans-serif;
}

.p3 {
font-family: "Lucida Console", "Courier New", monospace;
}

모든 브라우저와 장치에 범용적으로 설치된 웹 폰트가 있다. 하지만 100% 모든 곳에 지원하는 웹 폰트는 없기 때문에 fallback 폰트를 지정해줘야한다.

위 예시에서도 첫번째 폰트가 없으면 다음 폰트를 보여주는 방식으로 fallback 폰트를 지정해줬다.

주로 사용되는 웹 폰트는 다음 5가지이다.

  • serif
  • sans-serif
  • monospace
  • cursive
  • fantasy

font-style과 font-weight

font-style은 italic 텍스트를 사용할 때 설정한다.

1
2
3
4
5
6
7
8
9
10
11
p.normal {
font-style: normal;
}

p.italic {
font-style: italic;
}

p.oblique {
font-style: oblique;
}

font-weight 속성은 font의 두께를 설정한다.

1
2
3
4
5
6
7
p.normal {
font-weight: normal;
}

p.thick {
font-weight: bold;
}

font-size

폰트 사이즈를 설정하는 속성이다. 절대크기이거나 상대크기 일 수 있다.

❗️ 주의사항

폰트 사이즈를 사용하여 제목을 단락처럼 보이게 하거나 단락을 제목처럼 보이게하면 안된다. 제목은 h1 ~ h6, 단락은 p 태그와 같이 적절한 태그를 사용해야한다.

절대 크기

  • 정확한 크기를 설정한다.
  • 사용자가 글자 크기를 모든 브라우저에서 변경하는 것을 허락하지 않는다.(좋지 않는 접근성 이유 때문에)
  • 절대 크기는 결과물의 물리적인 크기가 알려져있을 때 유용하다.

상대 크기

  • 주변 요소의 상대적인 크기를 설정한다.
  • 브라우저에서 사용자가 글자 크기를 변경할 수 있도록 허락한다.

font-size를 em으로 설정하라.

브라우저 메뉴에서 사용자가 글자를 재설정하는 것을 허락하기위해 pixel 대신 em을 사용한다.

1em은 현재 폰트 크기와 동일하다. 브라우저에서 기본 폰트 사이즈는 16px이다. 즉, 1em = 16px

pixel / 16 = em 이라는 공식으로 계산할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
h1 {
font-size: 2.5em; /* 40px/16=2.5em */
}

h2 {
font-size: 1.875em; /* 30px/16=1.875em */
}

p {
font-size: 0.875em; /* 14px/16=0.875em */
}

%와 em의 조합하여 사용하기

모든 브라우저에 작동하는 해결책은 body 태그의 기본 폰트 크기를 %로 설정하는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
body {
font-size: 100%;
}

h1 {
font-size: 2.5em;
}

h2 {
font-size: 1.875em;
}

p {
font-size: 0.875em;
}

Google fonts

만약 HTML에서 기본적으로 제공하는 폰트가 싫다면 Google font를 사용해라.

Google fonts 사용법

1
2
3
4
5
6
7
8
<head>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Sofia" />
<style>
body {
font-family: "Sofia", sans-serif;
}
</style>
</head>

여러 폰트 사용하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<head>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Audiowide|Sofia|Trirong"
/>
<style>
h1.a {
font-family: "Audiowide", sans-serif;
}
h1.b {
font-family: "Sofia", sans-serif;
}
h1.c {
font-family: "Trirong", serif;
}
</style>
</head>

| 로 구분하여 사용할 수 있다.

font 효과 적용하기

구글 폰트는 기본적으로 font 효과를 제공한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<head>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Sofia&effect=fire"
/>
<style>
body {
font-family: "Sofia", sans-serif;
font-size: 30px;
}
</style>
</head>
<body>
<h1 class="font-effect-fire">Sofia on Fire</h1>
</body>

fonteffect

댓글 공유

문제

3×N 크기의 벽을 2×1, 1×2 크기의 타일로 채우는 경우의 수를 구해보자.

입력

첫째 줄에 N(1 ≤ N ≤ 30)이 주어진다.

출력

첫째 줄에 경우의 수를 출력한다.

예제 입력 1

1
2

예제 출력 1

1
3

내 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const N = +require("fs").readFileSync("/dev/stdin").toString().trim();

function fillTile(n) {
const DP = [0, 0, 3];

for (let i = 3; i <= n; i++) {
if (i % 2 !== 0) {
DP[i] = 0;
continue;
}
let k = i - 2;
DP[i] = DP[i - 2] * DP[2] + 2;
while (k >= 2) {
DP[i] += DP[k - 2] * 2;
k -= 2;
}
}
return DP[n];
}

console.log(fillTile(N));

해설

우선 n이 홀수인 경우는 경우의 수가 0이다.

그다음에 n이 4인 경우는 직접 그려보았다.

그랬더니 기존 유형을 벗어나는 특이한 모양 2개가 추가되는 것을 알 수 있었다.

DP[4] = DP[2] * 2 + 2 를 알 수 있었다.

n=4

이러한 모양은 n이 6인 경우에도 나타났다.

n=6

이를 토대로 점화식을 세워보았다.

DP[i] = DP[i-2] * DP[2] + DP[i-4] * 2 + DP[i-6] * 2 + … DP[2] * 2 + 2

  1. DP[i-2]에다가 DP[2]의 반복되는 패턴의 경우의 수를 곱해준다.
  2. 이후에는 특이한 케이스 2개씩 늘어나는 것만 고려해준다. 예를 들어 DP[2] * 2는 DP[i-2]에서의 특이 케이스 경우의 수를 의미한다.

댓글 공유

loco9939

author.bio


author.job