가로로 흐르는 탭 줄이나 칩 목록에서 스크롤바를 숨기고 싶을 때, 채팅창 옆의 두꺼운 회색 스크롤바를 얇고 옅은 것으로 바꾸고 싶을 때, 지금까지는 이렇게 썼다. .tabs::-webkit-scrollbar { display: none; } /* Chrome·Safari */ .tabs { -ms-overflow-style: none; } /* 옛 Edge·IE */ .tabs { scrollbar-width: none; } /* Firefox */ 세 줄이 전부 같은 일을 한다. ::-webkit-scrollbar 는 표준이 아니라 WebKit 이 2009...
Read More폼 검증 표시는 대개 이런 구조로 되어 있다. 입력칸이 틀리면 입력칸 테두리만 빨개지는 게 아니라, 그걸 감싼 박스에 배경이 깔리고, 라벨 색이 바뀌고, 아래에 숨어 있던 오류 문구가 나타난다. 브라우저는 input:invalid 로 입력칸 자신은 골라 줬지만 그걸 감싼 div 나 옆에 있는 label 은 고를 방법이 없었다. CSS 선택자는 아래로만 내려가지 위로는 못 올라갔기 때문이다. 그래서 검증 스타일은 JS 몫이었다. Bootstrap 은...
Read More주문번호, 시리얼, 자산 태그처럼 "다음 번호"를 만들어야 하는 값 중에는 숫자만으로 안 되는 것이 많다. SKU001 의 다음은 SKU002 고, 엑셀 열 이름 Z 의 다음은 AA 다. PHP 에서는 오래전부터 $s++ 가 이걸 해 줬다. 'ABC' 에 ++ 를 하면 'ABD' 가 되고 'ZZ' 는 'AAA' 가 된다. Perl 에서 넘어온 동작이다. 문제는 이 연산자가 문자열마다 다르게 구는 데 있다. '9'++ 는 문자열 '10' 이 아니라 정수 10 이 된다. '5.0'++ 는 실...
Read More이름이나 항목을 여러 개 나열해 보여주는 화면은 어디에나 있다. 결재선의 결재자, 회의 참석 부서, 글에 붙은 태그, 파일을 공유한 사람들. 배열을 implode(', ', $items) 로 붙이면 "기획팀, 개발팀, 디자인팀" 이 나오는데, 문장 안에 넣으려면 마지막 항목 앞에 "및" 이나 "and" 를 넣어야 한다. 이걸 손으로 하는 코드가 대개 이런 모양이다. $last = array_pop($items); $text = $items ? implode(', ', $items) . ' 및 ' ....
Read More다크 모드를 지원하는 CSS는 대개 이런 모양이다. 색마다 변수를 만들고, 미디어쿼리 안에서 같은 변수를 다시 선언한다. :root { --bg: #ffffff; --ink: #1a1a1a; --line: #e0e0e0; --muted: #6b7280; } @media (prefers-color-scheme: dark) { :root { --bg: #14171a; --ink: #f2f2f2; --line: #2c3136; --muted: #9aa4b2; } } 동작은 한다. 대신 변수 목록을 두 벌 관리하게 된다. 색을 하나 추가하면 두 곳에 써야 하고, 한쪽...
Read More목록 화면에 항목이 수천 개 있다. 사용자 화면에 실제로 보이는 것은 열 개쯤이다. 그런데 브라우저는 보이지 않는 나머지까지 전부 레이아웃하고 페인트한다. 각 항목의 높이를 계산하고, 문서 전체 높이를 구하고, 스크롤바 길이를 정한다. 이 낭비를 줄이는 방법은 오랫동안 자바스크립트였다. 화면에 보이는 만큼만 DOM에 넣고 스크롤에 따라 갈아 끼우는 가상 스크롤이다. 잘 동작하지만 직접 구현하면 스크롤 위치 복원, 키...
Read MorePHP 8.6이 2026년 11월 19일에 나온다. 세션 확장의 ini 기본값 셋이 바뀐다. 코드를 한 줄도 고치지 않아도 세션 쿠키에 붙는 속성이 달라진다. 같은 코드에 같은 요청을 보내고 응답 헤더만 비교하면 이렇다. # PHP 8.5.4 Set-Cookie: PHPSESSID=75586de12bb15eb5…; path=/ # PHP 8.6.0beta2 Set-Cookie: PHPSESSID=d6522d741bd160b6…; path=/; HttpOnly; SameSite=Lax 바뀌는 값은 셋이다. 설정 8.5까지 8.6부터 막는 것 sessio...
Read More입력값을 다듬는 코드는 대개 이런 모양이 된다. $amount = intval(preg_replace('/[^0-9]/', '', str_replace(',', '', trim($raw)))); 실행은 trim부터다. 그 다음 str_replace, preg_replace, intval 순서로 간다. 그런데 눈은 정반대로 움직인다. 왼쪽 끝의 intval을 먼저 만나고, 괄호를 따라 안쪽으로 파고들어 trim에 닿은 다음, 거기서 다시 밖으로 나오면서 순서를 되짚어야 한다. 그래서 보통은 임시 변수로 푼다. $trim...
Read More같은 카드 부품이 본문에도 들어가고, 좁은 사이드바에도 들어가고, 어두운 배너 안에도 들어간다. 자리마다 조금씩 달라야 한다. 사이드바에서는 설명을 감추고, 배너 안에서는 글자를 밝게. 화면 크기로 갈라 볼까 싶지만 그건 답이 아니다. 미디어 쿼리는 화면만 본다. 넓은 데스크톱 화면에서도 사이드바는 여전히 좁고, 같은 화면 안에서 본문에 있는 카드와 사이드바에 있는 카드는 구분되지 않는다. 부품이 알아야 하는 것...
Read More참고문헌 목록, 용어 정의, 시, 대본, 주소. 첫 줄은 왼쪽 끝에 붙고 둘째 줄부터 들여쓰는 내어쓰기(hanging indent)가 필요한 자리는 많다. 그리고 CSS에는 오랫동안 이걸 바로 말하는 문법이 없었다. 대신 모두가 같은 트릭을 썼다. .ref { padding-left: 2em; text-indent: -2em; } 블록 전체를 2em 밀어 넣고, 첫 줄만 2em 도로 당긴다. 결과는 내어쓰기처럼 보인다. 20년 넘게 쓰인 트릭이고 지금도 검색하면 이게 나온다. ...
Read More