입력값을 다듬는 코드는 대개 이런 모양이 된다. $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 MorePHP로 웹을 만들다 보면 이런 함수를 한 번쯤 짜게 된다. function sameOrigin(string $a, string $b): bool { $pa = parse_url($a); $pb = parse_url($b); return strtolower($pa['scheme'] ?? '') === strtolower($pb['scheme'] ?? '') strtolower($pa['host'] ?? '') === strtolower($pb['host'] ?? '') ($pa['port'] ?? null) === ($pb['port'] ?? null); } 리다이렉트 대상이 우리 사이트인지, 웹훅 URL이 허용된 호스트인...
Read More홈페이지에 올라간 영상이 200개를 넘는데 자막이 붙은 것은 하나도 없었다. 홍보영상, 뉴스에 나온 장면, 교가까지. 영상 아래에 내용을 텍스트로 적어둔 것은 있었다. 그런데 접근성 검수에서 그것으로는 안 된다고 걸렸고, 영상 하나하나에 사람이 자막을 받아 적을 수는 없었다. 결국 음성 인식으로 초안을 뽑고 손으로 다듬어 전부 붙였다. 그 과정에서 알게 된 것들을 정리한다. 자막 파일을 만드는 쪽과 웹에 붙이는 쪽 양...
Read MoreCSS 단위는 한동안 px, em, %, 인쇄용 pt 정도였다. 지금은 길이 단위만 세어도 마흔 개에 가깝다. rem이 들어오고, 뷰포트 단위가 들어오고, 그 뷰포트 단위가 다시 셋으로 갈라지고, 컨테이너 단위가 들어오고, 글꼴 단위마다 r 붙은 짝이 생겼다. 이걸 전부 외울 필요는 없다. 단위가 늘어난 방향은 하나다. "무엇을 기준으로 재는가"의 선택지가 늘어난 것이다. 기준을 알면 단위는 저절로 나온다. 단위는 기준으로 나뉜다 모...
Read More게시판 글쓰기 화면의 textarea는 늘 두 줄 높이로 시작한다. 세 줄째부터 스크롤바가 생기고, 사용자는 자기가 쓴 글의 윗부분을 못 보면서 계속 쓴다. 그래서 어느 프로젝트에나 이런 코드가 하나씩 있다. textarea.addEventListener('input', function () { this.style.height = 'auto'; this.style.height = this.scrollHeight + 'px'; }); 키를 누를 때마다 높이를 0으로 눌렀다가 scrollHeight만큼 다시 편다. 동작은 하지만...
Read More목록 화면 아래에는 대개 이런 줄이 붙어 있다. « ‹ 6 7 8 9 › ». 데스크톱에서는 이 줄이 아무 문제를 일으키지 않는다. 폭이 900px쯤 되니 번호 아홉 개에 이동 버튼 넷을 붙여도 여유롭다. 폰에서 같은 줄을 열면 사정이 달라진다. 그리고 대부분의 프로젝트가 같은 방식으로 이 문제를 처리한다 — 번호 개수를 줄인다. 데스크톱은 9개, 모바일은 4개. 이 타협을 오래 쓰다가 결국 버렸다. 번호를 줄이는 대신, 넘치면 가로로 ...
Read More서버에 접속해 cat /etc/os-release를 쳐본다. Rocky Linux 9.4가 나온다. 그래서 이 서버는 안전한가? 답할 수 없다. 버전 번호는 그 자체로 아무것도 말해주지 않는다. 9.4가 아직 지원되는지, 이미 다음 포인트 릴리스에 밀려났는지, 언제까지 보안 패치가 오는지 — 전부 밖에서 찾아봐야 아는 정보다. 이걸 매번 검색으로 해결하다 보면 결국 한 곳에 정착하게 된다. endoflife.date다. 먼저, 우리가 왜 이 걱정을 하게 됐나 E...
Read More메일 서명에 회사 로고를 넣기로 했다. 웹에서 하던 대로 data: URI로 이미지를 본문에 박아 넣으면 될 것 같았다. 외부 요청이 없으니 이미지 차단에도 안 걸릴 테고. 정확히 반대였다. 메일 클라이언트는 브라우저가 아니다 웹에서 data: URI는 요청 한 번을 아끼는 좋은 수단이다. 메일에서는 가장 나쁜 선택지다. 클라이언트 img src="data:image/png;base64,…" Gmail (웹·모바일)태그를 걷어낸다. 렌더되지 않는다 Outlook 데...
Read More