z-index 는 전역이 아니라 같은 쌓임 맥락 안에서만 비교된다. header 가 z-index 2, main 이 z-index 1 이면 main 안의 tooltip 은 z-index 999999 여도 header 아래에 깔린다 — 999999 는 main 안의 형제끼리만 비교되고, 맥락 밖으로 빠져나올 방법은 없다. 맥락은 z-index 를 준 positioned 요소 말고도 opacity 1 미만, transform·filter·clip-path, flex·grid 자식의 z-index, will-change, mix-blend-mode 로 의도치 않게 생긴다. 전략은 둘이다. 컴포넌트 안에서는 바깥 요소에 isolation: isolate 를 걸어 z-index 없이 맥락을 만든다 — 안쪽 1~5 는 그 안에서만 비교되고 밖으로 새지 않아, 컴포넌트가 바깥 z-index 값을 정하지 않아도 된다. 앱 레벨에서는 값을 숫자가 아니라 관계로 정의한다: base 0, above 1, below -1 을 두고 openButton 은 above + backdrop, dropdown 은 above + openButton 처럼 무엇 위에 있는지를 적는다. 상수는 쌓임 맥락별로 묶어 컴포넌트 옆에 둔다.



Footnotes

  1. z-index값을 체계적으로 관리하기 위한 방법(변수로 설정해서 상대적으로 값을 설정)을 제시하고 있다. ↩

#111

The clamp() CSS function clamps a value within a range of values between a defined minimum bound and a maximum bound. The function takes three parameters: a minimum value, a preferred value, and a maximum allowed value.

가로축 뷰포트 폭, 세로축 글자 크기. 360px 에서 1rem, 840px 에서 3.5rem 두 점을 직선으로 잇는다 — 기울기 2.5rem ÷ 30rem = 0.0833, 100 을 곱해 8.333vw. 직선을 폭 0 까지 늘린 y절편이 -0.875rem 이라 clamp(1rem, -0.875rem + 8.333vw, 3.5rem) 이 되고, 600px 에서 정확히 가운데인 2.25rem 이다. 폭도 rem 으로 바꿔 계산하는데 16 으로 나누는 건 루트 글자 크기가 16px 일 때만 맞다. 함정은 확대: 확대하면 CSS 뷰포트가 좁아져 vw 가 줄어서, 800px 창에서 200% 확대하면 화면 픽셀 52.7px 가 38.7px 로 오히려 작아진다(WCAG 1.4.4). 그래서 min·max 차이가 큰 제목에만 쓴다.

1vw 는 창 폭의 1% 다. 600px 창이면 1vw = 6px 이라 8.333vw = 50px, 여기에 y절편 -0.875rem(-14px) 를 더해 36px = 2.25rem 이고 clamp 가 16px~56px 로 자른다. 창 폭만 바꾸면 vw 몫은 창에 비례해 30·50·70·100px 로 늘지만 -14px 는 그대로라, 결과는 16·36·56·86px 이고 1200px 창의 86px 은 max 56px 에서 잘린다. vw 만 쓰면 원점을 지나는 비례선이라, 고정 rem 을 더해 선을 평행이동해야 원하는 두 점을 지난다.


Footnotes

  1. 유토피아는 디자이너와 개발자가 반응형 디자인의 유동성에 대한 체계적인 접근 방식을 공유할 때 나타납니다. x 개의 임의 중단점에 대해 설계하는 대신 요소가 비례하고 유동적으로 확장되는 시스템을 설계할 수 있습니다. ↩

  2. viewport 기반의 글꼴 크기를 clamp로 어떻게 구현하는지 설명해주고 있다. ↩

#109

텍스트 ellipsis는 컨텍스트마다 패턴이 다르다.

언제 — 먼저 어느 컨텍스트인지 가른다.

컨텍스트 어디로
display: table-cell 아래 절차
flexbox 맨 아래 참고 링크
여러 줄(multiline) 맨 아래 참고 링크

table cell

절차

  1. 표에 table-layout: fixed를 준다.
  2. 셀에 max-width: 0과 overflow: hidden 셋을 함께 준다.
table {
  table-layout: fixed;
  width: 100%;
}

col:nth-child(1) { width: 30%; }
col:nth-child(2) { width: 40%; }
col:nth-child(3) { width: 30%; }

td {
  max-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

확인: 긴 텍스트가 든 셀이 표를 옆으로 밀어내지 않고 …로 잘리는가.

함정 — table-layout: fixed와 max-width: 0은 반드시 함께여야 한다. overflow 셋만 주면 아무 효과가 없다.

/* ❌ 아무 효과 없음 */
td {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

display: table-cell은 width 제약 없이 content 크기에 맞게 늘어나서, overflow가 동작할 명시적 width bound가 없기 때문이다. 그리고 max-width: 0이 실제 0px이 되는 게 아니다 — table-layout: fixed 안에서 “이 셀은 content 기반으로 너비를 주장하지 않는다”는 시그널로 작동해, colgroup/th에서 받은 너비 안에서 overflow가 동작한다.

컬럼별 선택적 적용

td:not(.col-action) {
  max-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

td.col-action {
  white-space: nowrap;
}

셀 안에 복합 요소

버튼/배지 등이 텍스트와 함께 있을 때 inner wrapper에 위임.

td {
  max-width: 0;
}

td > div {
  display: flex;
  align-items: center;
  gap: 6px;
  overflow: hidden;
}

td > div > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

React 컴포넌트 패턴

TanStack Table size 옵션과 조합.

const columns = [
  columnHelper.accessor('name', {
    size: 200,
    cell: ({ getValue }) => (
      <span style={{ display: 'block', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
        {getValue()}
      </span>
    ),
  }),
]

<table style={{ tableLayout: 'fixed', width: '100%' }}>
  <colgroup>
    {table.getFlatHeaders().map(header => (
      <col key={header.id} style={{ width: header.getSize() }} />
    ))}
  </colgroup>
  ...
</table>

재사용 셀 래퍼:

function EllipsisCell({ children }: { children: React.ReactNode }) {
  return (
    <td style={{ maxWidth: 0 }}>
      <div style={{
        overflow: 'hidden',
        textOverflow: 'ellipsis',
        whiteSpace: 'nowrap',
      }}>
        {children}
      </div>
    </td>
  )
}

flexbox / multiline 참고


Footnotes

  1. flexbox | 파일명에 ellipsis 효과 적용, 단 파일 확장자는 제외. ↩

  2. :truncated 개념이 없기 때문에 ResizeObserver와 영역값을 체크해서 구현. ↩

#108

인라인 요소에 bold 스타일이 적용될 경우 레이아웃 시프팅 현상이 발생하기 때문에 해당 이슈를 해결하는 방법들.


Footnotes

  1. text-shadow로 우회하는 방법이 주 해결방법으로 올라왔다. ↩

  2. content 속성과, grid 레이아웃을 이용한 방법. ↩

#107
#106

discard1

git checkout -- <file>

git restore <file>

git reset --hard

리모트 브랜치 가져오기

git remote update

Footnotes

  1. 명령어로 discard를 하려면 ↩

#105
# 마지막 커밋 해시
git log --pretty=format:'%h' -n 1
# 유저정보
git config user.name
git config user.email
#101

Using Slack Slash Commands to Send Data from Slack into Google Sheets

순서를 기억하려고 적어둔 것이다. 방법은 위 링크에 있다.

  1. 사람들이 추천한 책을 기록한다
  2. 슬랙 -> 구글시트
  3. 슬랙 커맨드 설정 /book + 구글앱스 스크립트 url 연결1
  4. POST로 전송 받은 데이터값을 기반으로 데이터 처리 완료

Footnotes

  1. 꿀벌개발일지 :: 구글 앱스 스크립트에서 비동기 작업 추가하기 doPost에서 비동기 처리 ↩

#97
  1. 파일질라 서버를 설치
  2. Edit->Users->Add / 사용자 추가
  3. 제어판->시스템 및 보안->Windows Defender 방화벽->허용되는 앱 / (설정변경|다른 앱 허용) 파일질라 서버 추가
#95
33 중 27페이지