본문이 짧은 페이지에서 긴 페이지로 넘어가면 가운데 정렬된 레이아웃 전체가 왼쪽으로 몇 픽셀 밀린다. 다시 짧은 페이지로 가면 오른쪽으로 돌아온다. 메뉴를 오갈 때마다 로고와 본문이 좌우로 흔들린다. 모달을 열 때도 같은 일이 생긴다. 배경 스크롤을 막으려고 overflow: hidden을 걸면 스크롤바가 사라지고, 그만큼 페이지가 오른쪽으로 튄다. 원인은 같다. 세로 스크롤바가 화면 폭을 차지했다가 내놓기 때문이다. scrol...
Read More긴 안내 페이지나 약관, 문서 링크를 보내면서 "세 번째 단락 중간쯤 보세요"라고 덧붙인 적이 있을 것이다. 받는 사람은 페이지를 열고 스크롤을 내리면서 그 문장을 찾아야 한다. 단락마다 id가 달려 있으면 #id로 보낼 수 있지만, 남이 만든 페이지에는 그런 게 없는 경우가 대부분이다. 주소 끝에 #:~:text=찾을말을 붙이면 이 문제가 풀린다. 브라우저가 페이지를 연 뒤 그 문장을 찾아 화면 가운데로 스크롤하고 강조 표시까...
Read More주문 상태를 문자열로 들고 다니는 코드는 흔하다. DB 컬럼에는 pending, paid, shipped, cancelled가 들어 있고, 코드에서는 상수로 묶어 비교한다. final class Status { const PENDING = 'pending'; const PAID = 'paid'; const SHIPPED = 'shipped'; const CANCELLED = 'cancelled'; } function canShip(string $status): bool { return $status === Status::PAID; } 상수를 만들어 두어도 함수가 받는 것은 그냥 string이다. ...
Read More한글에 밑줄을 그으면 줄이 글자 아래쪽에 붙는다. 급, 입, 글처럼 받침이 있는 글자는 받침 바닥에 줄이 겹쳐서, 링크 하나만 걸어도 글자가 뭉개져 보인다. 영문은 괜찮다. g나 y처럼 아래로 내려오는 꼬리 부분은 브라우저가 알아서 줄을 끊고 비켜 간다. 이 "비켜 가기"를 정하는 속성이 text-decoration-skip-ink다. 기본값 auto는 한글을 비켜 가지 않는다. 그런데 2026년 5월 크롬 148에 all 값이 들어오면서 이 값이 Basel...
Read More사내 문서 검색창에 "연차 어떻게 내요?" 라고 치면 아무것도 안 나온다. 문서 제목은 "휴가 결재 절차" 다. LIKE '%연차%' 로는 "휴가" 를 못 잡고, 전문검색(FULLTEXT)을 붙여도 단어가 다르면 마찬가지다. 사람은 두 문장이 같은 얘기라는 걸 바로 아는데 DB 는 글자가 다르니 남이다. 이 간격을 메우는 것이 벡터 검색이다. 그동안은 별도 벡터 DB 를 세우거나 PostgreSQL 에 pgvector 를 붙여야 했는데, MariaDB 11.7 부터 VE...
Read More가로로 흐르는 탭 줄이나 칩 목록에서 스크롤바를 숨기고 싶을 때, 채팅창 옆의 두꺼운 회색 스크롤바를 얇고 옅은 것으로 바꾸고 싶을 때, 지금까지는 이렇게 썼다. .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