0823 - 0829

0823

31일 차 Sass

Sass의 특징

  • Sass로 작성된 코드는 브라우저가 해석할 수 없다.
  • Sass는 개발에 최적화된 단계, css는 배포에 최적화된 단계
  • postcss는 후처리기로 기능을 덧붙이는 역할을 한다.
  • css가 점점 강력해지고 있기 때문에 플러그인에 의존하는 형태로 변화할 가능성이 있다.
  • Sass와 Scss는 같은 것이다. 문법만 다르다. * 대부분 Ruby Sass말고 Node Sass를 사용한다. -> 점점 Node Sass는 지원하지 않을 것. Dart Sass로 넘어오는 추세

Dart Sass와 Node Sass의 차이점

  • Dart Sass에는 @use와 @forward가 생김
  • 나누기 연산에서 더하기나 빼기와 함께 이용하거나, 괄호로 묶어서 사용했었다.
    • Dart Sass에서는 나누기 연산을 허용하지 않는다.
    • sass의 math라는 빌트인 함수를 사용한다.
    • math.div(12px, 2) 이렇게 나누기를 사용한다.

설치 및 사용

"scripts": {
    "start": "npm run watch",
    "sass": "sass sass:css",
    "watch": "npm run sass -- --watch"
}
  • sass sass:css는 dart 사스를 이용해서 Sass 폴더 아래 있는 파일을 css로 컴파일하라는 뜻
  • watch는 sass 명령어를 재활용한다.
    • sass를 관찰 모드로 실행시킨다는 뜻
  • npm start를 입력하면 npm run watch가 실행된다.

컴파일 시 생기는 map 파일

  • 개발할 때는 sourceMapping이 없으면 오류를 난 곳을 찾기가 힘들다.
  • 빌드할 때 설정으로 생기지 않게 할 수 있다.

@use, @forward

dart sass에 새롭게 추가된 기능

  • @use는 모듈 형식으로 가져다 쓰겠다는 뜻
    • 모듈을 간단하게 쓰려면 @use './base a' as b 로 선언하면 b.변수로 사용 가능
    • @use './base a' as *로 쓰면 네임스페이스 없이 접근 가능
  • @forward는 파일을 한 곳으로 모아서 내보내주는 역할을 한다.
    • 한 파일 내에서 여러곳에 있는 sass 파일에 접근하려면 @use 명령어를 많이 사용해야 한다.
    • @forward 명령어로 한 곳의 파일에 sass 파일을 모아두면, 해당 파일만 @use로 받아와서 하나의 네임 스페이스로 변수들이나 mixin, 함수를 사용할 수 있다.

input 요소 실습

인풋 태그 기본 모양 제거

.form-input__input {
  // 폼 태그는 보통 기본 모양을 없애서 사용한다.
  appearance: none;

  &:focus {
    outline: none;
  }
}
  • 입력 서식의 기본 스타일 및 아웃라인 제거
  • 아웃라인은 추후 border 색상으로 재정의

function을 활용하여 px을 rem 단위로 변경

@use "sass:math";
// 루트 요소 기본 단위 --------------------------------------------------------------- /
$root-value: 16px !default;

// 단위 제거 함수 ------------------------------------------------------------------ /
@function removeUnit($value) {
  @return math.div($value, $value * 0 + 1);
}

// px을 rem 단위로 변경하는 함수 ------------------------------------------------------- /
@function rem($value, $base: $root-value) {
  @return (removeUnit(math.div($value, $base))) * 1rem;
}
  • dart sass는 나누기 연산시 math.div 내장함수를 사용하는데, 이를 사용하기 위해서는 위에 @use로 가져와야한다.
  • 단위가 있는 값이나 없는 값이나 모두 rem 단위로 변경하기 위해서 위와 같이 작성하였다.

input 태그 크로스 브라우징

input {
  // 인풋의 x 표시가 나오지 않게 함
  &::-ms-clear,
  &::-webkit-search-cancel-button,
  &::-webkit-search-results-button {
    display: none;
  }

  // 비밀번호에 한해서 눈모양 아이콘이 나오지 않게 함
  &::-ms-reveal {
    display: none;
  }

  // placeholder 스타일
  &::placeholder,
  &::-ms-input-placeholder {
    color: $form-placeholder-color;
  }
}

checkbox 스타일링 기본

  1. checkbox의 기본 스타일을 없앤다.
  2. 체크박스 영역에 새로 영역을 지정하고 absolute로 띄운다.
  3. 크로스 브라우징 문제때문에 checkbox에 바로 스타일을 입히는 것이 아니라 똑같은 크기의 label에 빈 span 요소를 만들어서 background 이미지를 보여주는 트릭을 사용한다.

그 외

  • :not() 선택자의 경우 IE11 이하를 지원하지 않는다.
  • readonly가 있는 속성을 선택하기 위해서는 크로스브라우징을 위해 [readonly]처럼 속성 선택자로 선택해야한다.
  • sass 구조상 중첩을 사용하지만, 빌드되면 밖으로 내보내서 구체성 점수를 낮추기 위해 @at-root를 활용할 수 있다.
  • box-sizing의 기본 값은 버튼은 border-box, a는 content-box이다.

0824

32일 차 Sass 이용해서 웹카페 프로젝트 진행하기

의존성 패키지 모듈

  • live-server : 라이브 서버 실행
  • htmlhint : HTML 파일에 대한 문법검사를 수행
  • chokidar-cli : htmlhint가 watch 옵션을 제공하지 않는 문제를 해결
  • sass : Dart Sass 설치
  • postcss-normalize : normalize.css
  • postcss : postcss를 사용하기 위한 패키지
  • autoprefixer : 자동으로 웹브라우저 별 접두사를 생성
  • postcss-csso : css 파일 최적화(압축)
  • postcss-combine-media-query : 미디어쿼리 병합
  • npm-run-all : 2개 이상의 npm 스크립트 명령을 직렬 또는 병렬로 수행

span 요소로 햄버거 버튼 디자인해서 활용하기

  • absolute top값을 %으로 줘서 위치를 설정한다.
  • 여기서 %는 부모의 세로너비의 영향을 받으므로, 원하는 위치에 배치하기 위해서는 자기 기준으로 내린 %만큼 다시 위로 올려줘야 한다.
  • reflow를 발생시키지 않기 위해서 올릴 때 transform 속성을 사용해서 -%만큼 Y축으로 올려준다.
  • is-active가 붙으면 애니메이션을 동작시키면서 햄버거 버튼을 X자로 바꾸는데 여기서 span을 감싸는 컨테이너에 overflow: hidden과 각 span의 translate 값을 지정해서 문제를 해결했다.
    • 중앙에 있는 span은 화면에서 사라지게 하고, 위 아래 span은 중앙으로 모아서 회전시켜 애니메이션을 만들었다.

grid 기본 문법

display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 50px 50px;
grid-template-areas:
  "logo member"
  "logo search";
  • 그리드를 사용하기 위해서는 우선 열의 크기를 정해줘야 한다.
    • repeat 함수를 지정하여 첫 번째 매개변수에 열의 개수를 넣고, 두 번째 매개변수에 열의 크기를 정한다. 1fr은 균등하게 크기를 나눈다는 것을 뜻한다.
  • 행은 50px의 크기로 두 개를 지정하였다.
  • grid-template-areas 에는 영역의 행, 열에 맞춰서 이름을 지정할 수 있다.
    • 그리드 아이템에 grid-area: “이름” 을 지정하면 해당 영역에 맞게 매칭되어 배치된다.

0825

33일 차 Sass 이용해서 웹카페 프로젝트 진행하기

알고리즘 문제풀이

카카오 블라인드 테스트에서 출제된 신규 아이디 추천 문제를 풀었다.
조건이 많은 문자열 문제였지만 테스트케이스를 돌려보면서 걸리는 항목이 있었다.
이번 기회에 항상 해야지 하고만 생각했던 정규표현식에 대해 정리하고, 앞으로 문자열 관련 문제를 풀 때 정규표현식을 활용하면 도움이 되겠다는 생각이 들었다.

정규 표현식(Regular Expression)

정규 표현식(Regular Expression)은 문자열에서 특정 내용을 찾거나 대체 또는 발췌하는데 사용한다.
정규 표현식을 생성하는 방법에는 두 가지가 있다.

  1. 정규 표현식 리터럴을 사용하는 방법
  2. RegExp 객체의 생성자 함수를 호출하는 방법

정규식 리터럴은 스크립트가 불러와질 때 컴파일된다. 만약 정규식이 상수라면, 이렇게 사용하는 것이 성능을 향상시킨다.
반면, 생성자 함수를 사용하면 정규식이 실행 시점에 컴파일된다. 정규식 패턴이 변경될 수 있는 경우, 혹은 사용자 입력과 같이 다른 출처로부터 패턴을 가져와야 하는 경우에는 생성자 함수를 사용한다.

단순 패턴

단순 패턴은 문자열을 있는 그대로 대응시키고자 할 때 사용된다.
예를 들어, /abc/라는 패턴은 문자열에서 정확히 ‘abc’라는 문자들이 순서대로 나타나야 대응된다.
부분 문자열을 포함하고 있더라도, ‘abc’를 정확하기 포함하지 않는다면 대응되지 않는다.

특수 문자를 사용한 패턴

  • 정규식 패턴 안의 .은 임의의 문자 한 개를 의미한다.
  • 앞선 패턴을 최소 1번 반복하려면 패턴 뒤에 + 기호를 붙인다.
  • | 기호를 사용하면 or의 의미를 가진다.
  • []내의 문자는 or로 동작한다.
  • 범위를 지정하려면 []내에 -를 사용한다.
  • \d는 숫자를 의미한다. \D\d와 반대로 동작한다.
  • \w는 알파벳과 숫자를 의미한다. \W\w와 반대로 동작한다.
  • ^는 특정 단어로 시작하는지 검사한다.
  • $는 특정 단어로 끝나는지 검사한다.
  • 이를 활용하여 /^\d+$/는 모두 숫자인지 검사하는 패턴이다.
  • \s는 여러 가지 공백문자를 의미한다. (스페이스, 탭 등)

플래그를 사용한 검색

정규식은 플래그를 설정해줄 수 있으며, 이를 통해 쩐역 검색 또는 대소문자 구분 없는 검색을 수행할 수 있다.
이 플래그들은 각기 사용될 수도 있고 함께 사용될 수도 있고 순서에 구분이 없다.

  • g : 전역 검색
  • i : 대소문자 구분 없는 검색
  • m : 다중행 검색
  • s : .에 개행 문자도 매칭 (ES2018)

정규식에 플래그를 포함시킨 문법은 아래와 같다.

const regExp = /정규식패턴/플래그들;
  • 정규식 패턴은 두개의 슬래쉬 안에 작성해야 한다.
  • 플래그는 정규식에 합쳐지는 정보다. 이것들은 나중에 추가되거나 제거될 수 없다.

정규식에서 쓰이는 메소드

  • exec : 대응되는 문자열을 찾는 RegExp 메소드이다. 정보를 가지고 배열을 반환한다. 대응되는 문자열을 찾이 못했다면 null을 반환한다.
  • test : 대응되는 문자열을 찾는 RegExp 메소드이다. true나 false를 반환한다.
  • match : 대응되는 문자열을 찾는 String 메소드이다. 정보를 가지고 있는 배열을 반환한다. 대응되는 문자열을 찾지 못했다면 -1을 반환한다.
  • search : 대응되는 문자열을 찾는 String 메소드이다. 대응된 부분의 인덱스를 반환한다. 대응되는 문자열을 찾지 못했다면 -1을 반환한다.
  • replace : 대응되는 문자열을 찾아 다른 문자열로 치환하는 String 메소드이다.
  • split : 정규식 혹은 문자열로 대상 문자열을 나누어 배열로 반환하는 String 메소드이다.

괄호를 둘러싼 패턴

정규식 패턴에 괄호를 사용하면, 그 부분을 별도로 대응시키면서 대응된 부분을 기억한다.
예를 들어 /(a)bc(d)/는 ‘abcd’에 대응하면서 ‘a’와 ‘d’를 기억한다. 괄호로 감싸진 문자열을 불러오려면, 배열 요소를 사용한다.

괄호로 감쌀 수 있는 문자의 개수에는 제한이 없다. 반환된 배열은 찾아낸 모든 것들을 갖고 있다.

const re = /(a)bc(d)/;
let str = "abcd";
let newstr = str.replace(re, "$2 and $1");
console.log(newstr);

// 결과
d and a

정규 표현식을 잘 활용한다면 많은 문제를 해결할 수 있다.
예를 들어 이번 문제를 풀면서 빈 문자열인 경우 다른 텍스트로 대체하는 방법을 찾지 못했었는데, 문자열.replace(/^$/, '대체문자') 방식을 이용하면 간단하게 해결할 수 있었다.
다만 그렇게 풀었을 때의 문제점은 정규 표현식의 다양한 활용법에 대해 익숙하지 않은 사람들이 봤을 때에 가독성이 떨어질 수 있다는 점인대 이 부분에 대해서는 조금 더 고민해봐야겠다.

core Web Vital

훌륭한 UX를 제공하기 위한 지표에 대한 지침을 제시하는 Google 이니셔티브이다.
사용 경험에 영향을 미치는 다양한 측정 가능한 값들 중에서 구글이 중요하다 강조하는 아래의 3가지 매트릭스를 말한다.
이 3가지 매트릭스에 굳이 코어라는 단어를 붙여 부르는 이유는 웹사이트에 방문하는 유저들의 경험을 좌우하는 여러 요소 중 가장 기본이자 핵심 지표이기 때문이다.

LCP (Largest Contentful Paint)

  • 인식되는 로딩 속도를 측정하는 항목으로, 뷰포트에 포함된 모든 HTML 요소들이 브라우저 화면에서 렌더링 완료되는데까지 걸리는 시간의 길이를 말한다.
  • 2.5초 이하인 경우 좋음, 2.5초 이상 4초 이하인 경우 개선이 필요, 4초 이상인 경우 나쁨으로 평가
  • 이미지나 비디오같은 요소에 대한 최적화를 동해 지표 개선을 할 수 있다.

FID (First Input Display)

  • 웹 페이지와 사용자간의 상호작용에 대한 항목
    • ex) 웹 사이트에서 스크롤, 클릭 등 여러 상호작용에 대한 응답
  • 이 지표가 중요하게 보는 것은 요청 받은 액션을 처리하는데 걸리는 시간이 아니라 브라우저에서 다음 액션이 가능하게 되는 시간까지의 길이(입력 지연을 시키는 시간)이다.
  • 사용자 환경에서 사용자가 체감하는 지표이기 때문에 테스트 환경에서 확인할 수 있는 지표가 아니다.
    • 구글은 다양한 테스트 환경에서 측정 가능한 총 차단시간 (Total Blocking Time)을 FID 지표를 대신해서 측정하라고 말한다.
    • TBT는 페이지로드 중 발생하는 입력 작업 불가능 시간의 합계이므로 항상 낮을수록 좋다.
  • 100ms 이하인 경우 좋음, 100ms 이상 300ms 이하인 경우 개선 필요, 300ms 이상인 경우 나쁨으로 평가

CLS (Cumulative Layout Shift)

  • 시각적 안정성을 측정하는 항목
  • 어떤 페이지에 들어갔을 때 갑작스럽게 발생하는 레이아웃 이동의 정도를 합산 이동 거리라는 개념을 도입해서 만들어낸 지표
  • 0.1 이하인 경우 좋음, 0.1 이상 0.25 이하인 경우 개선 필요, 0.25 이상인 경우 나쁨으로 평가

기타 요소

  • 모바일 친화성 : 웹 페이지가 모바일 브라우징에 최적화 되어있는가에 대한 평가
  • 세이프 브라우징 : 페이지에 방문자의 의도를 속이려는 콘텐츠가 있는가? 혹은 악성 코드나 애드 웨어등이 심겨져 있지 않은 가에 대한 평가
  • HTTPS : 웹 사이트가 HTTPS를 제공하고 있는 가에 대한 평가
  • 방해요소 : 콘텐츠 소비를 방해하는 전면 광고와 같은 방해 요소가 있는가에 대한 평가

왜 SEO에 중요한가?

구글 연구 결과에 따르면 코어 웹 바이탈의 기준을 충족한 웹 페이지의 경우 방문자가 사이트에서 이탈할 가능성이 24%나 낮다고 한다.
소비자 피드백을 중시하는 랭킹 알고리즘이라 할 수 있는 랭크 브레인을 고려하면 UX를 개선하기 위해 이용되는 코어 웹 바이탈 매트릭스는 SEO에서 중요한 의미를 갖는다고 말할 수 있다.

SVG 스프라이트

SVG 이미지를 스프라이트 이미지로 사용하기 위해서는 기존의 jpg, png 스프라이트 이미지들과 사용법이 다르다.
우선 Spritebot 서비스를 이용해서 SVG 스프라이트 이미지를 만든다.
생성된 svg 파일을 열어보면 구별 가능한 ID를 가진 심볼 그래픽을 볼 수 있다.
Spritebot이 생성한 스프라이트 이미지를 사용하는 방법은 2가지이다.

  1. 스프라이트 이미지를 로드 한 후 사용법 생성된 파일을 이미지 폴더에 넣은 후, <svg><use /></svg> 요소를 사용해 이미지를 로드한다.
    이 방법은 SVG 심볼을 재사용 하는 방법으로 필요할 경우 SVG 코드를 변경하거나, 애니메이션을 적용하는 등 활용도가 높다.
<svg><use xlink:href="./이미지-폴더/sprite-sheet.svg#icon-pricetag" /></svg>
  1. 스프라이트 이미지를 HTML 문서에 포함할 경우 사용법 HTML 문서에 SVG 스프라이트 코드를 삽입해서 사용할 경우, 먼저 불필요한 속성 xmlns를 제거하고 적절한 ID를 설정한다.
    그리고 화면에 렌더링 되지 않도록 hidden속성을 <svg> 요소에 추가한다.
<svg hidden id="svg-sprites">
  <symbol id="icon-network" viewBox="0 0 64 64">...</symbol>
  <symbol id="icon-onlinecart" viewBox="0 0 64 64">...</symbol>
  <symbol id="icon-presentation3" viewBox="0 0 64 64">...</symbol>
  <symbol id="icon-pricetag" viewBox="0 0 64 64">...</symbol>
  <symbol id="icon-safe" viewBox="0 0 64 64">...</symbol>
</svg>
  • 동일한 문서에 심볼이 있으니 심볼 ID를 사용해 바로 문서에서 재사용 가능하다.
    • 앞서 이미지를 첨부한 경우보다 코드가 간결해지는 장점이 있다.
  • 하지만, 여러 문서에서 동일한 SVG 스프라이트 이미지를 사용하려면 이 방법은 좋은 방법이라고 볼 수 없다.
<svg><use xlink:href="#icon-pricetag" /></svg>

메인 영역 실습

focus-visible & focus-within

  • focus-within은 포커스를 받는 요소의 부모 요소에서 지정하는 가상 클래스 선택자로 자식에 있는 요소가 포커스 받았을 때 부모에게 스타일을 지정해줄 수 있다.
  • focus-visible은 포커스를 받는 요소에게 지정하는 가상 클래스 선택자로 키보드로 접근한 포커스만 스타일이 적용된다.

속성 선택자

  • 선택자[속성 *= '값'] : 값을 포함하는 요소
  • 선택자[속성 ^= '값'] : 값으로 시작하는 요소
  • 선택자[속성 $= '값'] : 값으로 끝나는 요소

반응형 이미지

  • 부모 컨테이너 width를 %로 주고 margin을 좌우로 auto로 준다.
  • 이미지에 max-width를 100%로 주고 height는 auto로 준다.

반응형 iframe

  • 반응형 iframe을 사용하기 위해서는 iframe을 감싸는 컨테이너가 필요하다.
  • iframe의 위치는 absolute로 지정하여 부모 컨테이너로부터 top: 0; left: 0; 위치에 있게 한다.
  • 부모 컨테이너의 width는 100% height는 0으로 지정하고 원하는 해상도비율만큼 padding-top을 준다.
  • 그리고 iframe의 높이와 너비를 100%로 지정하면 원하는 비율이 나오게 된다.

사용자 정의 데이터 속성

  • html 속성으로 data-로 시작하는 값을 작성하고 이를 css 가상 요소 선택자를 활용하여 사용할 수 있다.
  • 가상 요소 선택자의 content 값으로 attr(사용자정의데이터속성명)을 입력하면 해당하는 값을 사용 가능하다.

커스텀 셀렉터

@custom-selector :--변수 클래스1, 클래스2, 클래스3

:--변수 {
  // 스타일
}
  • 위와 같이 지정하면 클래스 1,2,3을 :--변수 키워드 한 번으로 사용 가능하다.
  • 아직 안정적인 버전이 아니라서 웹팩의 postcss-preset-env 값을 변경해줘야 한다.
  • post-preset-env : 플러그인을 모아두는 곳

그 외

  • 본문 중간에 영어로 된 단어가 있는 경우 lang="en" 속성 설정을 고려한다.
  • 아웃라인 스타일 작성하기에 border은 레이아웃이 무너질 수 있으므로 shadow로 작성하는 것이 더 좋다.
  • font-size 속성에 clamp(최소값, 기본값, 최대값)을 이용해서 폰트 사이즈를 반응형으로 사용할 수 있다.


34일 차 Sass & Tailwind css

메인 영역 실습

동그란 모양의 이미지 모양대로 텍스트 흘러가기 하기

  • border-radius를 50%로 설정해서 동그란 모양을 만들고, overflow: hidden을 주어 튀어나온 부분을 숨긴다.
  • shape-outside: circle(50%);를 주면 글자가 정말 동그란 이미지가 있는것처럼 주변을 흐르게 된다.


Tailwindcss

TailwindCSS는 다른 utility-first CSS에 비해 custom이 쉽고 확장에 용이하다는 장점이 있다.
여러 가지 플러그인을 추가하거나 직접 제작할 수 있고, 문서화도 잘 되어있다.

기본 사용법

  1. tailwindcss를 설치한다. npm i -D tailwindcss@latest
  2. tailwind config 파일을 생성한다. npm tailwind init
  3. tailwind를 쉽게 사용하기 위해 tailwindcss intelliSens 익스텐션을 설치하고 그에 맞게 설정한다.
  4. tailwind config 파일을 설정한다.
module.exports = {
  purge: ["src/**/*.html"],
  darkMode: "class", // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
};
  1. package.json 파일을 설정한다.


그 외

  • word-break: keep-all;는 반응형으로 줄일 때, 한 글자가 아니라 한 단어씩 줄 바뀜이 일어나도록 한다.
  • npm 명령어를 동시에 실행시킬 때 옵션이 -s 면 직렬실행이고, -p면 병렬실행이다.

0827

35일 차 Tailwind css

오늘은 Tailwindcss를 프로젝트 스타일링 하는데에 직접 사용해보면서 실습 위주의 시간을 보냈다.

Tailwindcss를 사용하여 로그인 페이지 작성 코드

<!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" />
    <title>Tailwindcss를 활용한 로그인 페이지 스타일링</title>
    <link
      href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="./css/style.css" />
  </head>

  <body>
    <!-- 라이트 / 다크 모드 토글 버튼 -->
    <!-- 1. 자바스크립트로 제어하기 위한 버튼 클래스 지정 (toggle-theme-button) -->
    <!-- 2. body 영역을 기준으로 오른쪽 상단에 배치 / 3. 글자 및 배경색상 / 4. 라운딩 처리 / 5. 버튼 크기 고정(커스텀) -->
    <button
      type="button"
      class="toggle-theme-button absolute top-5 right-5 bg-gray-300 text-gray-700 p-4 rounded-md w-[200px]"
    >
      다크모드 보기
    </button>
    <!-- 전체 콘텐츠 컨테이너 -->
    <!-- 1. 플렉스로 배치 (모바일 및 데스크탑 스타일) / 2. 높이 / 3. 텍스트 색상 / 4. 다크모드 텍스트 및 배경 색상 /  -->
    <div
      class="flex justify-center items-start md:items-center h-screen text-gray1 dark:text-white dark:bg-gray-900"
      style=""
    >
      <!-- 데스크 탑에서 보여지게 될 로그인 콘텐츠 박스(테두리) -->
      <!-- 1. 가로 크기(full) / 2. 데스크탑 최대 가로크기(md:min-w-screen-sm) / 3. 데스크탑에만 border / 4. padding-->
      <div
        class="w-full md:max-w-screen-sm md:border md:rounded-2xl md:border-gray5 px-5 py-10 md:py-16 md:px-12"
      >
        <!-- 패스트 캠퍼스 브랜드 로고 -->
        <h1 class="logo">
          <a href="#">
            <picture>
              <!-- 운영체제 테마 전환 모드 -->
              <source
                srcset="./images/fastcampus-logo-dark.png"
                media="(prefers-color-scheme: dark)"
              />
              <source
                srcset="./images/fastcampus-logo.png"
                media="(prefers-color-scheme: light)"
              />
              <!-- 커스텀 테마 전환 모드 -->
              <img src="./images/fastcampus-logo.png" alt="fastcampus" />
            </picture>
          </a>
        </h1>

        <!-- 패스트 캠퍼스 슬로건 -->
        <!-- 1. 제목과 슬로건 사이 여백(margin) / 2. 글자 크기 및 색상 / 3. 다크모드 글자 색상-->
        <p class="text-3xl mt-5">
          인생을 바꾸는 교육,
          <strong class="block font-normal">패스트 캠퍼스.</strong>
        </p>

        <!-- 회원 로그인 폼 -->
        <!-- 1. 슬로건과 로그인 폼 사이 여백(margin) -->
        <form class="mt-10">
          <fieldset>
            <!-- 스크린리더를 위한 유틸리티 클래스 적용 -->
            <legend class="sr-only">회원 로그인 폼</legend>

            <!-- 아이디 입력 서식 -->
            <div>
              <!-- 스크린리더를 위한 유틸리티 클래스 적용 -->
              <label for="userId" class="sr-only">아이디</label>
              <!-- 1. 테두리 관련 속성 / 2. 안쪽여백 / 3. 아웃라인 제거 -->
              <!-- 4. :focus 스타일 - 선색상 black / 다크모드 선색상 primary -->
              <input
                id="userId"
                name="userId"
                class="input"
                type="text"
                placeholder="아이디"
                required
              />
            </div>

            <!-- 비밀번호 입력 서식 -->
            <div class="mt-3">
              <label for="userPassword" class="sr-only">비밀번호</label>
              <!-- 반복되는 스타일을 @apply 디렉티브 활용 하여 tailwind.css 파일에 작성할 것 -->
              <!-- 
                .input{
                  @apply ;
                }
                .input:focus{
                  @apply ;
                }
              -->
              <input
                id="userPassword"
                name="userPassword"
                class="input"
                type="password"
                placeholder="비밀번호"
                required
              />
            </div>

            <!-- 자동 로그인 및 비밀번호 찾기 그룹 컨테이너 -->
            <!-- 1. 플렉스 배치 / 2. 상하 여백(margin) /  -->
            <div class="flex justify-between items-center my-4">
              <!-- 자동 로그인 및 비밀번호 -->
              <!-- 1. relative(input 요소의 컨테이닝 블록 역할)  -->
              <div class="relative">
                <!-- tailwind.css 파일에 추가되어 있는 코드는 주석으로 처리한 후 작성해보기 -->
                <!-- 1. 웹브라우저 스타일 제거(appearance) / 2. absolute(영역을 차지하지 않도록) -->
                <!-- 3. 가로 세로 크기 / 4. 위치 미세 조정 / 5. 배경이미지 커스텀을 위한 auto-login 클래스-->
                <input
                  class="appearance-none absolute w-[16px] h-[16px] top-[2px] auto-login"
                  type="checkbox"
                  id="autoLogin"
                  name="autoLogin"
                />
                <!-- 1. 체크박스(input)와 겹치지 않도록 왼쪽에 padding 지정 -->
                <!-- 2. 기본 배경이미지 및 선택상태 배경이미지 커스텀 -->
                <!-- 
                  backgroundImage: theme => ({
                    'checkbox-default': "url('/../images/checkbox-default.png')",
                    'checkbox-checked': "url('/../images/checkbox-checked.png')",
                  }),
                 -->
                <!-- 3. 배경이미지 반복하지 않기, 배경이미지 왼쪽 중앙 배치 -->
                <label
                  for="autoLogin"
                  class="pl-6 bg-left bg-no-repeat bg-checkbox-default"
                >
                  자동 로그인
                </label>
              </div>

              <!-- 비밀번호 찾기 링크 -->
              <a href="#">비밀번호 찾기</a>
            </div>

            <!-- 1. 가로 및 세로 크기 / 2. 테두리 라운딩 / 3. 글자 크기, 색상, 굵기 / 4. 배경 색상 /-->
            <button
              type="submit"
              class="w-full p-4 text-white bg-primary font-bold text-lg rounded-md"
            >
              로그인
            </button>
          </fieldset>
        </form>

        <!-- 회원가입 링크 -->
        <!-- 1. 여백(margin) / 2. 텍스트 가운데 정렬 -->
        <p class="mt-6 text-center">
          아직 계정이 없으신가요?
          <!-- 1. 글자 굵기, 밑줄 제거, 글자 색상 / 2. 다크모드 글자 색상 -->
          <a class="font-bold underline text-gray1 dark:text-white" href="#"
            >간편 회원가입</a
          >
        </p>
      </div>
    </div>
    <script defer src="js/main.js"></script>
  </body>
</html>
  • tailwindcss는 위와 같이 클래스 스타일링을 컴포넌트처럼 필요한 속성을 조립하여 사용한다.
  • 기존에 있는 tailwindcss 클래스 외에 필요한 코드가 있다면 tailwind.css에서 오버라이드 해서 사용한다. style.css는 건드릴 일이 없다.
  • tailwindcss는 무조건 모바일 기준으로 시작한다. 데스크탑을 재정의하는 방식으로 사용하는 것이 기본이다.
  • @apply는 css 클래스 속성대신 클래스 이름의 조합으로 스타일을 요청할 수 있게 할 수 있다.
    • tailwind.css에서 아래와 같이 tailwind의 클래스를 조합하여 스타일을 지정할 수 있다.
.input {
  @apply w-full border border-gray5 rounded-md p-4 outline-none focus:border-black dark:border-primary;
}
* input 클래스를 호출하여 선언된 tailwind 클래스에 지정된 스타일을 불러올 수 있다.
  • 커스텀 속성을 설정하기 위해서는 jit 모드를 사용해야 한다.

0828

첫 프로젝트

오늘부터 다음주까지 프로젝트 주간이다.
자유 주제에 원하는대로 웹 사이트를 구축하면 되는데, 우리 팀은 카카오 프렌즈샵의 모바일 클론 코딩과 웹을 새롭게 리뉴얼하여 반응형 페이지로 만들기로 했다.

처음에는 어느정도 큰 변화를 주고자 하였으나, 변화를 줬을 때 기존 회사의 기획 의도와 우리가 리뉴얼하는 이유 모두를 만족시키는 기획을 뽑는 것이 쉽지 않다는 것을 깨닫게 되었다.
점심먹고 모여서 밤까지 계속해서 회의를 하고 고민한끝에 겨우 기획 결과물을 내게 되었다.

다음 주는 우리의 프로젝트 과정을 TIL로 작성하며 녹여내어볼까 한다.
모두가 열심히 하는 만큼 좋은 결과가 있었으면 좋겠다.

0829

프로젝트 시작

처음으로 할 일은 기획한 것을 디자인 시안으로 옮기는 일이었다.
시안으로 옮기기에 여러명이 달라 붙으면 효율이 나오지 않을 것이라고 판단해 나와 다른 팀원은 성능적으로 어떻게 끌어올릴지 자료를 조사하였고, 다른 두명의 팀원은 시안으로 옮기는 일을 했다.


그라운드 룰 작성

팀명

웹으로바꿔조 (권고안)

김둘이둘

TwoKim-TwoLee (2K2L)

둘둘이조

2(김+이)

니니즈

키워드

협동

정신력

데스크탑사용자

가보자고

열쩡열쩡열쩡!

성장

즐겁게 하자

3조가 해내죠?

우리의 Ground Rule

밥잘챙겨먹기

상대방 말 끝까지 들어주기

쉬는 시간 꼭 가지기

회의 할 때 의견 적극적으로 내기

다른 사람 의견 잘 들어주기

문제가 생기면 함께 해결하기

주기적으로(하루 3번) 진행상황 공유하기


커밋 컨벤션

commit 메세지 컨벤션

  • feat : 새 기능 추가 (mixin 등)
  • fix : 버그, 주석 및 기타 수정
  • style : CSS등 UI 디자인 변경
  • refactor : 리팩토링
  • env : 환경 설정 및 수정
  • docs : 문서 수정 (ex. README.md)
  • rename : 폴더, 파일명 수정 및 이동
  • remove : 폴더, 파일 제거
  • chore : 빌드 업무 수정, 패키지 매니저 수정.
  1. 제목과 본문을 한 줄 띄워 분리하기
  2. 제목은 영문 기준 50자 이내로
  3. 제목 첫글자를 대문자로 (feat: Add unitchange function)
  4. 제목 끝에 . 금지
  5. 제목은 명령조
  6. Github - 제목(이나 본문)에 이슈 번호 붙이기
  7. 본문은 영문 기준 72자마다 줄 바꾸기
  8. 본문은 어떻게보다 무엇을에 맞춰 작성하기


클래스 네이밍 컨벤션

BEM

BEM 표기법을 기준으로 추후에 상세히 정할 예정


적용 기술 서치

웹 콘텐츠 구성

사용자가 검색하기도 전에 Google은 검색 색인에 웹페이지에 관한 정보를 구성한다.

그렇다면 검색에서 정보를 구성하는 방법은 무엇인가?

웹 크롤러는 사용자가 검색하기 전에 수 천 억개에 달하는 웹페이지에서 정보를 모아 이를 검색 색인에 정리한다.

크롤링 프로세스는 이전의 크롤링 작업을 통해 수집한 웹 주소 목록과 웹사이트 소유자가 제공한 사이트맵에서부터 시작된다. 크롤러는 웹사이트를 방문한 다음 사이트에 있는 링크를 사용하여 다른 페이지를 찾는다. 또한 크롤러 소프트웨어는 새로운 사이트, 기존 사이트의 변경사항, 깨진 링크를 주의 깊게 살핀다. 크롤링할 사이트, 크롤링 횟수 및 각 사이트에서 가져올 페이지 수는 컴퓨터 프로그램에서 결정된다.

Google에서 사이트 소유자가 Google에서 사이트를 크롤링하는 방법을 세밀하게 설정할 수 있도록 Search Console을 제공한다. 사이트 소유자는 페이지 크롤링 처리 방식을 상세하게 설정하는 것은 물론 재크롤링을 요청하거나 ‘robots.txt’라는 파일을 사용하여 페이지가 아예 크롤링되지 않도록 할 수도 있다.

웹은 끊임없이 커지는 도서관과 같다. 수 십 억권에 달하는 책을 보관하고 있지만 중앙집중식 저장 시스템이 갖춰져 있지 않은 상태에 비유할 수 있다. Google은 웹 크롤러라는 소프트웨어를 사용해서 공개된 웹페이지를 발견한다. 사람들이 웹에서 콘텐츠를 탐색할 때와 비슷하게, 크롤러는 웹페이지를 살펴보고 해당 웹페이지에 있는 링크를 따라간다. 이 크롤러는 여러 링크를 넘나들며 이러한 웹페이지에 대한 데이터를 Google 서버로 가져온다.

크롤러가 웹페이지를 찾으면 구글 시스템에서 브라우저와 마찬가지로 해당 페이지의 콘텐츠를 렌더링한다. 이 때 키워드 및 웹사이트 최신 정보에 이르는 주요 신호를 기록하며 검색 색인에서 주요 신호를 추적한다. 웹 페이지 색인이 생성되면 웹페이지에 포함된 모든 단어의 색인 항목에 웹페이지를 추가한다.

요약

  1. 웹 크롤러를 이용해 공개된 웹 페이지 검색
  2. 찾은 웹 페이지의 콘텐츠 렌더링 및 색인 생성
  3. 검색어와 색인을 이용해 결과 제공


사이트맵

사이트맵은 사이트에 있는 페이지, 동영상 및 기타 파일과 그 관계에 관한 정보를 제공하는 파일이다. 구글과 같은 검색엔진은 이 파일을 읽고 사이트를 더 효율적으로 크롤링한다. 사이트맵은 내가 사이트에서 중요하다고 생각하는 페이지와 파일을 구글에 알리고 중요한 관련 정보를 제공한다.

ex) 페이지가 마지막으로 업데이트된 시간, 페이지의 대체 언어 버전

→ 사이트 맵은 리치 미디어 콘텐츠가 많은 경우 추가 정보를 제공하면 검색에 적절하게 사용할 수 있다.

사이트맵 제작

  1. 사용할 사이트맵 형식 결정
  2. 자동 or 수동으로 사이트맵 제작
  3. 사이트맵을 robots.txt에 추가하거나 Search Console에 직접 제출하여 구글에 제공

사이트맵 형식

  • XML
  • RSS, mRSS, Atom 1.0
  • 텍스트

형식과 관계없이 사이트맵은 1개당 50MB와 URL 50,000개로 제한된다.

→ 더 클 경우 목록을 여러 개의 사이트맵으로 나눠야 한다.

사이트맵 제작 웹사이트

https://www.xml-sitemaps.com/ 을 이용하여 사이트맵을 만드는 방법

먼저, 웹사이트에 접속 후 사이트맵을 만들고자 하는 웹사이트의 도메인을 입력한다.

다음으로 More options 버튼을 클릭하여 사이트맵에 추가적인 정보를 삽입할 것인지 설정한다.

  1. Include “Page Last modification” 은 페이지가 마지막으로 변경된 날짜에 대한 데이터를 사이트맵에 추가하고 싶은가에 대해 설정하는 항목이다. 사이트맵에 이 정보를 입력하면 크롤러가 변경되지 않은 페이지를 재크롤링 하는것을 방지할 수 있다.
  2. Automatically calculate “Page Priority” attribute는 페이지별 중요도를 페이지 뎁스(홈페이지로부터 해당 페이지에 도달하기까지 필요한 클릭 혹은 페이지의 수)에 기반하여 자동으로 설정해주는 기능이다. 이 기능을 활성화하면 따로 페이지별 중요도를 설정하지 않아도 자동으로 산출되어 지정된다.
  3. Pages”Change Frequency” attributes는 웹사이트의 콘텐츠가 얼마나 자주 업데이트되는지에 대한 정보를 사이트맵에 추가할 수 있는 기능이다. 기본 설정으로는 비활성화되어있지만 “항상”부터 “전혀 되지 않음”까지 상황에 맞게 선택할 수 있다.

상황에 맞게 모두 지정하였다면 START 버튼을 눌러 사이트맵 제작을 시작한다. 사이트맵 제작은 짧게는 수 분, 길게는 수십 분이 걸릴 수 있다.

사이트맵 생성이 완료되면 버튼을 눌러 완성된 사이트맵을 다운로드 할 수 있다.


robots.txt

robots.txt는 웹사이트에 대한 검색엔진 로봇들의 접근을 조절해주고 제어해주는 역할, 그리고 로봇들에게 웹사이트의 사이트맵이 어디있는지 알려주는 역할을 한다. robots.txt 파일은 사이트의 루트에 위치한다.

robots.txt 파일을 설정하지 않으면 구글, 네이버 등 각종 검색엔진 로봇들이 웹사이트에서 찾을 수 있는 모든 정보를 크롤링하여 검색엔진 검색결과에 노출시킨다. 만약 웹사이트 내 특정 페이지가 검색엔진에 노출되지 않기를 바란다면 robots.txt파일을 설정하여 이를 제어할 수 있다.

다음은 두 가지 규칙이 포함된 간단한 robots.txt 파일이다.

User-agent: Googlebot
Disallow: /nogooglebot/

User-agent: *
Allow: /

Sitemap: http://www.example.com/sitemap.xml
  1. 이름이 Googlebot인 사용자 에이전트는 http://example.com/nogooglebot/으로 시작하는 URL을 크롤링할 수 없습니다.
  2. 그 외 모든 사용자 에이전트는 전체 사이트를 크롤링할 수 있습니다. 이 부분을 생략해도 결과는 동일합니다. 사용자 에이전트가 전체 사이트를 크롤링할 수 있도록 허용하는 것이 기본 동작입니다.
  3. 사이트의 사이트맵 파일은 http://www.example.com/sitemap.xml에 있습니다.

설정법

robots.txt는 html이 아닌 일반 텍스트 파일로 작성하며 사이트의 루트 디렉토리에 위치해야 한다.


스켈레톤 UI

스켈레톤 컴포넌트는 데이터를 가져오는 동안 콘텐츠를 표시하는 컴포넌트이다.

보통 페이지가 시작할 때 실행하는 ajax 통신 시 결과를 받아오기 전까지 스켈레톤 UI, 스피너 등 로딩 애니메이션을 보여주는데 사용할 수 있을까 하는 의문이 든다…


Image Lazy Loading

Image Lazy Loading이란 페이지 안에 있는 실제 이미지들이 실제로 화면에 보여질 필요가 있을 때 로딩을 할 수 있도록 하는 테크닉이다. 웹 페이지 내에서 바로 로딩을 하지 않고 로딩 시점을 뒤로 미루를 것이라 볼 수 있다.

→ 웹 성능과 디바이스 내 리소스 활용도 증가, 연관된 비용을 줄이는데 도움을 줄 수 있다.

장점

  1. 성능 향상
    페이지 초기 로딩 시 필요한 이미지 수를 줄일 수 있다. 리소스 요청을 줄여서, 유저가 사용할 수 있는 제한된 네트워크 대역폭의 경쟁을 줄여서 다른 리소스들을 더 빠르게 처리해서 다운로드하도록 한다.
  2. 비용 감소
    이미지가 보여지지 않으면 절대 로딩하지 않으므로, 페이지 내에서 전달할 총 바이트 용량을 줄일 수 있다. 특히나 페이지의 제일 상단에만 서비스를 이용하는 유저에게 효과적이다.

어떻게 적용할 것인가?

lazy loading의 기본적인 방법은 지금 당장 필요하지 않은 모든 요소들을 잠시 로딩을 지연하는 것이다. 따라서 사용자 화면에 보여지지 않는 이미지들은 로딩을 지연시킬 수 있다.

사용자가 페이지에서 스크롤을 아래로 내림으로써, 이비지의 플레이스홀더는 뷰포트에 다가오게 되고 뷰포트에 보여지게 되면 이미지를 로딩하도록 트리거를 일으킨다.

img 태그를 이용한 일반적인 방법

Lazy loading 이미지들은 두 단계로 나눌 수 있다.

첫 번째는, 이미지 로딩을 사전에 막는 것이다. 일반적으로 img 태그를 이용해서 이미지를 로드하기 위해 src 속성을 이용한다. html내 이미지가 어디에 존재하든 상관없이, 만약 브라우저가 src 속성을 가지면 이미지를 무조건 로드한다.

이와 같이 이미지들의 로딩을 지연 시키려면 src 속성 대신 다른 사용자 정의 속성에다가 url을 넣는 것이다.

<img
  data-src="[https://ik.imagekit.io/demo/default-image.jpg](https://ik.imagekit.io/demo/default-image.jpg)"
/>

위 방식으로 이미지 로드를 사전에 막았으니, 이제는 브라우저에게 해당 이미지를 언제 로딩할 것인지 알려주어야 한다.


출처

(Robots.txt와 Sitemap.xml 알아보기)https://www.twinword.co.kr/blog/basic-technical-seo/

(사이트맵 제작 방법)https://www.twinword.co.kr/blog/3-different-ways-to-generate-and-submit-sitemap/

(구글검색센터)https://developers.google.com/search/docs/advanced/guidelines/get-started?hl=ko

(레이지 로딩)https://helloinyong.tistory.com/297

태그:

카테고리:

업데이트: