- 마크업 언어란 문서가 화면에 표시되는 형식을 나타내거나 데이터의 논리적인 구조를 명시하기 위한 규칙들을 정의한 언어의 일종
- 전 세계적으로 통용되는 웹 문서는 HTML(Hyper Text Markup Language)이라는 마크업 언어를 활용하고 있다.
- 국내에서는 HTML 마크업 개발자를 "퍼블리셔" 로 지칭하는 경우가 많음
- 퍼블리싱은 웹 사이트를 제작할 때, 웹 디자이너가 디자인한 것을 웹 표준성과 접근성에 부합하도록 재정리하는 것
1. HTML
dialog 태그
- https://fullystacked.net/portal/
- 부모 중에
transform
, translate
, rotate
, scale
, perspective
or filter
CSS 속성을 가지는 요소가 있으면 position: fixed
속성이 깨짐
<dialog>
요소나 popover
속성을 가지는 요소는 영향 받지 않음
- React 의
portal
, Vue의 Teleport
가 <dialog>
나 popover
속성으로 완전히 대체 가능?
Node
table 태그
<tr>
은 항상 <table>
, <thead>
, <tbody>
, <tfoot>
내부에서만 사용
<td>
안에는 <tr>
을 직접 넣을 수 없음, <table>
를 넣는 것은 가능
button 태그
type
속성의 기본 값은 submit
- button 태그 안에 div 태그 사용?
Per the HTML standard a <button>
may only contain Phrasing content.
A div element is not a valid element for Phrasing Content.
- button 태그 안에 a 태그 사용 이슈?
- Table 첫 줄 colspan 적용 시 width 스타일 적용 안먹음,
colgroup
으로 지정 참고
a태그
- a태그 안에 사용 가능한 태그?
- https://stackoverflow.com/questions/6393827/can-i-nest-a-button-element-inside-an-a-using-html5
- 상호작용이 있는 요소 (
a, audio(controls 속성이 있는 경우), button, details, embed, iframe, img(usemap속성이 있는 경우), input(hidden 상태가 아닌 경우), keygen, label, menu(type속성값이 toolbar인 경우), object(usemap속성이 있는 경우), select, textarea, video(controls 속성이 있는 경우)
) 를 제외한 태그는 중첩 가능
- a태그 안에 h1 태그 넣는것도 접근성 위반?
- https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element
- 버튼이나 링크와 같은 대화형 콘텐츠가 없는 한 전체 paragraphs, list, tables, section 등 감쌀 수 있음
- 사양에 맞지는 않지만 button이 form 안에 있지 않을 때,
<a><button></button></a>
형태가 동작은 가능 함
button과 a의 구분
- 스크립트 작동 등 기능을 위해 사용하는 경우 :
button
- 페이지의 이동 또는 팝업 페이지 호출을 위해 사용하는 경우 :
a
- 둘 다는 아니지만 클릭 이벤트가 있는 영역임을 알려주기 위해 사용되는 경우 : CSS
cursor:pointer
hidden 속성
속성 선택자
~=?
- Since theme can have multiple names, it allows you to target a single theme inside the space-separated list. Visit MDN for more information.
rel
속성
- mdn
: 현재 문서와 링크된 문서 사이의 연관 관계 명시
: 검색엔진들이 링크에 대한 더 많은 정보 수집을 위해 사용할 수 있는 속성
: href 속성이 설정되어 있어야만 사용 가능
: <link>
, <a>
, <area>
, <form>
에서 유효 / 각 요소에따라 사용할 수 있는 속성값 다름
: 기본값 없음 / 속성값이 없는 경우, 둘 사이에 하이퍼 링크가 있는 것 외에는 특별한 관계가 없다고 판단
<a>
의 rel
속성
- alternate : 프린트 페이지나 번역된 페이지와 같이 해당 문서의 대체 버전에 대한 링크를 나타냄.
- author : 해당 문서의 저자에 대한 링크를 나타냄.
- bookmark : 즐겨찾기(bookmarking)에 사용하는 고유 주소(Permanent URL)를 나타냄.
- external : 링크된 문서가 현재 문서와 같은 사이트 내에 있지 않음을 나타냄.
- help : 도움말 문서에 대한 링크를 나타냄.
- license : 해당 문서의 저작권 정보에 대한 링크를 나타냄.
- next : 연관된 문서들의 모음 중 다음 문서에 대한 링크를 나타냄.
- nofollow : 유료 링크와 같이 검색 엔진이나 봇(bot) 등이 추적해서는 안 됨을 나타냄.
- noreferrer : 사용자가 하이퍼링크를 클릭할 때 브라우저가 HTTP 리퍼러 헤더(referer header)를 전송해서는 안 됨을 나타냄.
- noopener : 하이퍼링크를 따라 연결되는 어떠한 브라우징 컨텍스트(browsing context)도 오프너(opener)여서는 안 됨을 나타냄.
- prev : 문서들 중에서 이전 문서를 나타냄.
- search : 해당 문서를 위한 검색 도구를 나타냄.
- tag : 현재 문서를 위한 키워드(tag)를 나타냄.
- https://taedonn.tistory.com/32
noopener
: window.opener가 기존 탭에 접근하는 걸 차단 (window.opener가 null 반환)
: noopener를 사용하면 target = _self
, _top
, _parent
도 ₩_blank₩처럼 새 탭으로 열림
: target="_blank"
를 통해 새 탭을 열면 기존 탭의 참조를 반환하기 때문에 window.opener.location
사용해 기존 탭의 URL 변경 가능 (기존 탭과 똑같이 생긴 피싱 사이트로 기존 탭을 변경해 사용자의 개인정보 빼가는 시나리오 가능)
: MDN 에서도 target="_blank"
사용 시 rel="noopener"
추가해 window.opener
API의 악의적인 사용 방지 권장 (최신브라우저 자동 적용)
: 링크된 페이지에서 window.opener
로 부모 윈도우 참조할 수 없게, 링크된 페이지와 부모 윈도우 별개의 프로세스로 취급되어 서로 퍼포먼스에 영향 X
noreferrer
: 새 탭에서 기존 탭의 참조를 가져오는 걸 차단
: 기존 탭에 대한 참조를 차단했기 때문에, noopener처럼 window.opener가 null 반환
: 다른 페이지로 이동 시 링크를 건 페이지의 정보를 브라우저가 Referer HTTP 헤더로 송신 X
: https://developer.mozilla.org/en-US/docs/Web/Security/Referer_header:_privacy_and_security_concerns
2. CSS
prefers-color-scheme 미디어 쿼리
CSS 변수
box-decoration-break
- 박스가 여러 줄(또는 열)로 나누어질 때, 박스에 적용된 스타일을 어떻게 처리할지 결정하는 CSS 속성
slice
, clone
CSS pre-processor
sticky
- 적용 가능 조건
- 부모 요소가 스크롤 가능해야 함
- 오프셋 요소가 하나라도 있어야 함
grid
화면전환
수직 정렬
- https://wit.nts-corp.com/2017/09/25/4903
vertical-align
적용 시 원하는 결과가 나타나지 않는다면
- 각 인라인 레벨 요소의 baseline, top, bottom과 라인박스의 상단과 하단 경계의 위치 파악해보기
- 부모요소에 보이지 않는 상상의 박스인 strut 검토, 인라인 레벨 요소들이 이 strut 에 따라 수직정렬 된다는 점 유의
- inline, inline-block 요소에는 decender 를 위한 하단 여백 존재 (참고)
clip-path
font-size
- 다른
font-family
에 동일한 font-size
를 적용한 경우 각각 다른 높이값을 가짐
- 폰트는 각 글자가 그려질 컨테이너의 일종인 em-square(혹은 UPM, units per em)을 정의. 이 square는 상대적인 단위를 사용. 일반적으로 1000 단위로 설정 됨. 하지만 1024, 2048 혹은 다른 어떤 것도 될 수 있음. 상대적인 단위를 기반으로 폰트의 매트릭스가 설정 됨(ascender, descender, capital height, x-height 등). 일부 값들은 em-squre의 바깥으로 흘러 넘칠 수 있음. 브라우저에서 상대 단위는 원하는 font-size에 맞게 조정 됨.
content-area
background
값이 적용되는 영역
- 폰트 매트릭스에 의해 정의 됨
- 항상 line-box의 중앙에 위치
line-box
- line-box의 높이는 자식 요소의 높이값을 기반으로 함 (자식 요소의 가장 높은 지점에서 가장 낮은 지점까지를 계산한 값)
- line-box의 높이는 자식 요소의 content-area 높이가 아님
content-area
높이는 폰트 매트릭스에 의해 정의 됨
line-height
높이가 line-box
의 높이 계산에 사용 됨
line-height
와 vertical-align
속성을 기반으로 계산됨
- 우리가 정확히 볼 수 없으며 CSS로도 제어 불가능
em
- 계산된 높이값이 아닌
font-size
를 기반으로 동작
line-height
line-height : 1
을 설정하는 것은 나쁜 습관
- 단위 없는 값은
content-area
가 기준이 아닌 font-size
의 상대값, content-area
보다 line-height
값이 작아질 수 있음
- 라인박스의 높이를 지정하는 속성, 블록 레벨 요소에는 요소내의 라인박스의 최소 높이를 지정. 대체되지 않은 인라인 요소에서는 라인 박스 높이를 계산하는데 사용할 높이 지정.
- (line-height - font-size) / 2 = 반 행간 값
- 인라인 박스는 라인박스 안에서 vertical-align 속성 값에 의해 수직 정렬되는 영역
- 라인 박스는 여러 인라인 박스를 구성하는 영역으로 하나의 줄에 있는 인라인 박스의 가장 높은 지점과 낮은 지점을 둘러싸고 있는 박스
normal
- user agent에 따라 달라짐
- 보통 1이나 1.2이지만 정확하지 않음
- 폰트 매트릭스 값을 기반으로 계산하기에
font-family
에 따라 달라짐
<number>
<length>
<percentage>
- https://velog.io/@ursr0706/line-height-%EC%86%8D%EC%84%B1
vertical-align
줄바꿈
word-wrap: break-word;
word-break: break-all;
word-wrap: break-word;
word-break: keep-all;
word-break
word-wrap
(=overflow-wrap
)
- https://developer.mozilla.org/en-US/docs/Web/CSS/word-wrap
- 처음에 마이크로소프트에서 표준이 아니고 접두어가 없는
word-wrap
으로 나왔고, 대부분 브라우저에서 똑같은 이름으로 구현되었다가 요즘은 overflow-wrap으로 다시 지어지고, word-wrap은 동의어가 됨
- 박스의 가로 영역을 넘친 단어 내에서 임의의 분리 여부를 결정
- 넘친 단어의 임의의 분리는 음절에서 발생하며 white-space 속성이 기본 값(normal) 일 때만 적용
normal
(초깃값)
: non-CJK 단어넘침 O, CJK 단어넘침 X
break-word
: non-CJK 단어넘침 X, CJK 단어넘침 X
animation
transition
transform
box-shadow
checkbox
- checkbox에 사용되는 [-][v] 이미지는 브라우저 Agent 기본 디자인을 바꾸는 것임
네트워크 문제로 이미지가 노출되지 않는 상황에서도 보여야 하므로 data uri 방식으로 inline화
css로 그리는 방식은 버그 생길 수 있는 확률이 큼
- bootstrap
: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")
- 인코딩 사이트 : https://yoksel.github.io/url-encoder/
resize
letter-spacing
flex
- flex
: flex-grow(Flex 아이템이 Flex 컨테이너 내에서 얼마나 더 많은 공간을 차지할 수 있는지를 결정, flex-grow 값이 1로 설정되면 해당 Flex 아이템은 가능한 모든 공간을 차지하려고 노력) / flex-shrink(Flex 아이템이 Flex 컨테이너 내에서 얼마나 축소할 수 있는지를 결정, 일반적으로 1로 설정되며 컨테이너가 축소되면 Flex 아이템도 같은 비율로 축소) / flex-basis(Flex 아이템의 초기 크기를 결정, auto로 설정되면 아이템의 크기를 기본 크기로 유지)
: flex: 1
은 Flex 아이템이 가능한 모든 공간을 차지하려고 하며 크기를 유지하려고 노력, Flex 컨테이너 내에서 사용 가능한 공간을 아이템들 사이에 동등하게 분배하려고 함
: flex: 0 1 auto
은 Flex 아이템이 축소 가능하며 초기 크기를 유지하려고 함
scroll
불필요한 영역 노출 및 새로 고침 방지
body {
overscroll-behavior-y: none;
}
모달 외 스크롤 발생 막음
.modal {
overscroll-behavior-y: contain;
}
pointer-events
이벤트가 부여된 요소를 제어하기 위하여 여러가지 방법을 모색할 수 있다.
CSS 속성 중에서 강제로 이벤트를 제어 할 수 있는 방법 pointer-events 라는 속성을 사용할 수도 있다.
https://velog.io/@godud2604/CSS-CSS-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%A0%9C%EC%96%B4-pointer-events
상대단위
- em
해당 단위가 사용되고 있는 요소의 font-size 속성 값에 비례해서 결정되는 상대 단위
font-size가 html 요소부터 시작해 여러 상위 요소들을 거치면서 상속되기 때문에 계산 복잡, 재사용 어렵고 유지보수 힘들어짐
- rem
최상위 요소(HTML에서는 html)의 font-size 속성 값에 비례해서 결정되는 상대 단위
em보다는 가급적 rem 사용
- %
%를 쓰는 요소의 부모 요소를 기준으로 길이를 반환한다.
- vw
화면 기준 너비
vw,vh는 화면의 전체 길이를 상대적으로 반환하기 때문에 스크롤바를 포함한 길이를 반환
- vh
화면 기준 너비
vw,vh는 화면의 전체 길이를 상대적으로 반환하기 때문에 스크롤바를 포함한 길이를 반환
가상선택자
table
anchor-positioning
3. Image
파일 확장자
https://velog.io/@gil0127/svg-vs-png-vs-jpg
svg
webp
- GIF, JPG, PNG 포맷을 대체하기 위해 개발됨
- 장점
: 이미지 품질이 같을 때 WebP 파일의 크기가 다른 포맷의 파일에 비해 훨씬 작음 (특히 GIF파일을 WebP 파일로 바꾸면 이미지 품질은 유지하면서 파일 크기는 절반 이하로 줄어듬)
- 단점
: 모든 브라우저가 WebP 지원하지 않음
: 대체가 없으므로 브라우저에서 이미지를 표시할 수 없으면 이미지가 전혀 표시되지 않음
svg vs webp
- 더 작은 파일 크기와 더 정확한 이미지가 필요한 경우 SVG가 적합
- 더 빠른 로딩 시간과 더 작은 파일 크기를 위해 약간의 정확도를 희생해도(약간의 이미지 왜곡) 괜찮다면 WebP가 나을 수 있음
Data URIs
svg
4. Font
- 폰트는 콘텐츠이자 브랜드이며 사용자 경험, 단순 한 에셋처럼 로드하고 있다면 개선 필요
- 글꼴은 글리프 모양만 정의한느 것이 아니라, 메트릭(ascent, descent, line gap, x-height, kerning and ligature)을 정의 함, 리플로우 일으킴
웹폰트
-
https://www.jonoalderson.com/performance/youre-loading-fonts-wrong/
-
LCP, CLS(https://web.dev/articles/cls?hl=ko) 등 핵심 성능 지표와 접근성에 직접적인 영향을 줌
-
권장 적용 방법
- 시스템 폰트를 우선 적용
- WOFF2 단일 포맷 사용
- 레거시 브라우저(IE11)를 반드시 지원해야 하는 경우 WOFF를 조건부 대체로 추가하되 모든 사람에게 제공 X
- 지능적 서브셋팅
- 프리로드 및 인라인 선언을 통한 @font-face 최적화
- 변수 폰트의 선택적 활용
- 폴백 폰트의 메트릭 정렬을 권장
- 폴백 폰트와 웹 폰트 간 메트릭 차이로 인한 레이아웃 이동 방지
- size-adjust, ascent-override, descent-override, line-gap-override 속성을 활용해 메트릭 맞출 수 있음
- Font style matcher 활용
- 라이선스 제약(서브셋 금지, 조회수 기반 과금 등) 점검
- 완전한 글꼴 모음은 스타일 당 400-800KB가 될 수 있음
- WebPageText, Glyphhanger, fonttools 같은 도구로 폰트 크기와 로딩 시점 측정하고 예산을 설정해 빠른 초기 렌더링과 일관된 타이포그래피 달성
-
https://d2.naver.com/helloworld/4969726
- 사용자가 폰트를 설치하지 않아도 디자이너가 원하는 타이포그래피를 웹 페이지에 구현할 수 있게 하는 기술
-
FOUT(=flash of unstyled text)
- 웹폰트가 유저의 기기에 다운로드 되기 전, 텍스트가 시스템 폰트로 노출되는 현상
-
FOIT(=Flash of invisible text)
font-display
CSS 속성을 적용하면 웹폰트 파일 다운로드 전 까지 텍스트를 숨길 수 있지만, 콘텐츠가 아예 보이지 않게 되어 추천하지 않음
-
웹폰트 최적화 방법
-
폰트 파일 용량 줄이기
- WOFF 2.0 (WOFF 보다 30~50% 더 압축된 형식), WOFF(Web Open Font Format) 형식 사용
- 서브넷 폰트 (불필요한 글자 제거하고 사용할 글자만 남겨둔 폰트)
unicode-range
속성 (유니코드로 지정한 글자에만 웹 폰트 적용, 등록된 글자가 텍스트에 없으면 웹 폰트 다운 요청 X)

-
텍스트가 항상 보이게
- IE 계열 브라우저는 FOUT 방식으로, 그 외의 브라우저는 FOIT 방식으로 렌더링 차단 처리
font-display: swap
적용해 항상 FOUT 으로 처리
-
폰트 간 차이 줄이기
-
preload
옵션으로 먼저 로딩하기
<link>
태그의 rel 속성에 preload 옵션 사용하면 해당 리소스를 다른 리소스보다 빨리 로딩
- 주로 폰트, 이미지, 스크립트, 비디오 파일 등 페이지에서 중요도가 높은 자원을 의도적으로 먼저 로딩할 때 사용
- preload 옵션으로 다운로드하는 리소스가 많아질 수록 처음 렌더링 시간이 늦어짐
- 브라우저 지원 여부
- 성능 개선 사례 참고
CJK(중국어, 일본어, 한국어)
Pretendard
CSS
- font-display
- swap: 대체 텍스트 즉시 렌더링한 다음 준비가 되면 웹 글꼴 바꿈 (FOUT)
- block: 최대 3초동안 텍스트를 숨긴 다음 아직 준비되지 않은 경우 대체 표시 (FOIT)
- fallback: 매우 짧은 시간(~100ms) 블락 후 대체 표시, 준비가 되면 웹 글꼴 바꿈
- optional: 즉시 대체 표시하지 않고 조건이 좋지 않은 경우 교체되지 않을 수 있음
- font-synthesis: none; 브라우저가 굵기(bold), 기울임(italic)꼴을 위조하지 않도록 처리
- 실제 제공하는 weight 와 styles 만 사용
5. 프린트
페이지 레이아웃 관련 속성
.print-no-page-break {
page-break-before: avoid;
page-break-after: avoid;
page-break-inside: avoid;
}
.avoid-page-break {
page-break-before: avoid;
page-break-after: avoid;
}
.example {
page-break-inside: auto;
}
page-break-after
page-break-before
page-break-inside
Chrome 개발자도구 - 프린트 화면 확인

6. 크로스브라우징
IE
Windos 11 에서는 더이상 IE 11 지원 X
나머지 Windows dㅔ서도 2022년 6월 25일부터는 데스크탑 인터넷 익스플로러 11 지원 종료 예정
하지만 익스플로러에서만 구동되는 사이트와 기타 문제때문에 'Internet Explorer 11 모드(Edge용)'라는 기능으로 여전히 Windows 11에서 지원하고 있음
Windows 11 에서 IE 11 사용하는 방법 참고 : https://oldnew.tistory.com/693
https://www.theverge.com/2021/5/19/22443997/microsoft-internet-explorer-end-of-support-date
window 배율
window 브라우저는 모니터 크기+해상도에 따라 권장 비율이 달라짐 (100%, 125%, 150% 등)
단순히 해상도만으로 정해지는건 아니고 EDID(디스플레이 정보)에서 반환하는 화면크기 정보와 조합해서 권장 배율이 달라집니다.
https://www.reddit.com/r/Windows10/comments/6we5ys/how_does_windows_10_calculate_the_recommended_dpi/