본문으로

이 누리집은 대한민국 공식 전자정부 누리집입니다.

회원가입
메뉴검색
전체 메뉴 닫기

팝업 안 그리드(표) 샘플

모달·윈도우 팝업 안에 목록(표) 을 넣을 때의 표준입니다. 시안 정본은 ppt-41-42전체항목 그리드이고, 퍼블이 그걸 그리는 규칙을 그대로 씁니다.

💡 한 줄 요약 — 스크롤 컨테이너는 표를 감싸는 div 하나, 그리고 높이를 직접 준다.
<div class="board-tbl 스크롤러"> > <table> 구조에 display:block · height · overflow-y:auto 를 주고, thead thposition:sticky;top:0 + 배경.
퍼블도 똑같이 합니다 — util.css:322 .shuttle-cont .board-tbl{display:block;overflow-y:auto;height:235px}
⚠ flex 로 높이를 '받으려' 하지 마세요.
.modal-cont > .wrap > .grid 처럼 중첩해 놓고 flex:1 로 높이를 흘려보내는 방식은 단계마다 min-height:0 이 필요하고, 한 곳만 빠져도 조용히 실패합니다 (표가 안 줄고 → 스크롤바가 안 생기고 → 부모가 대신 스크롤되어 머리글·버튼이 밀려 나갑니다).
실제로 통합코드 팝업에서 이 실패를 여러 번 겪었습니다. 높이는 스크롤러에 직접 주는 게 표준입니다.
부득이 flex 를 써야 하면 flex:1 1 0 로 두세요 — auto 는 기준이 '내용 크기'라 축소 계산이 어긋납니다.

1. 기본형 — 모달 + 목록

가장 흔한 경우. 래퍼에 board-tbl 을 주면 퍼블 표 스킨(테두리·머리글 배경·셀 여백)이 전부 따라옵니다. 거기에 스크롤 클래스 하나만 덧붙이면 끝입니다.

<div class="modal-cont"> <div class="board-tbl smp-grid"> <%-- ← 스크롤러 --%> <table> <caption>…(스크린리더용)…</caption> <colgroup><col style="width:70px"><col style="width:110px"><col></colgroup> <thead><tr><th scope="col">번호</th>…</tr></thead> <tbody>…</tbody> </table> </div> </div> .smp-grid{display:block; height:clamp(120px, calc(100vh - 360px), 280px); overflow:auto;} .smp-grid > table{min-width:420px;} /* 이보다 좁아지면 가로 스크롤 */ .smp-grid thead th{position:sticky; top:0; z-index:5; background:var(--bg-secondary-weak);}

2. 검색영역이 있는 경우 — 검색은 고정, 목록만 스크롤

검색영역을 스크롤러 밖에 두는 것이 전부입니다. 흔한 실수는 .modal-cont 전체를 스크롤시키는 것 — 그러면 내리는 순간 검색영역이 위로 사라집니다.
맨 왼쪽 체크박스 열전체선택 처리도 함께 넣어 두었습니다.

<div class="modal-cont"> <div class="smp-srch">…검색 UI + 검색 버튼…</div> <%-- 스크롤러 → 항상 보인다 --%> <div class="board-tbl smp-grid"><table>…</table></div> </div> <%-- 체크박스 칸 : 시안과 같은 55px. 퍼블 체크박스는 span.form-checkbox 로 감싼다 --%> <colgroup><col style="width:55px"><col style="width:70px">…</colgroup> <th scope="col"> <span class="form-checkbox"> <input type="checkbox" id="smpChkAll"> <label for="smpChkAll"><i class="blind">전체 행 선택</i></label> <%-- i.blind 필수 --%> </span> </th> <%-- 전체선택은 직접 묶는다. 퍼블 [data-toggle="all"](utill.js:324)은 .cate-list 전용이라 표엔 안 걸린다 --%> $(document).on("change", "#smpChkAll", function(){ $("#목록 input[type=checkbox]").prop("checked", this.checked); }); <%-- 검색영역 높이만큼 그리드를 낮춘다 --%> #모달ID .smp-grid{height:clamp(120px, calc(100vh - 500px), 240px);}

3. 윈도우 팝업(comn.fw.popLayout) 안의 목록

⚠ 윈도우 팝업 레이아웃은 퍼블 CSS 를 로드하지 않습니다(normalize/popup/style.css 만). 그래서 data-tbl 같은 퍼블 클래스가 안 걸립니다 — 표 스킨을 값으로 직접 그려야 합니다. 페이지 자체가 창(또는 iframe) 높이에 맞아야 하므로 html,body{height:100%} 부터 잡습니다. 실제 적용 사례는 data/dwnlSvc/unifCodeSearch.jsp 입니다.

html,body{height:100%; overflow:hidden;} <%-- 문서 전체가 스크롤되면 안 된다 --%> .pop-wrap{display:flex; flex-direction:column; height:100%;} .pop-wrap .pop-body{flex:1 1 auto; min-height:0; display:flex; flex-direction:column; overflow:hidden;} .pop-wrap .pop-srch{flex:none;} <%-- 검색영역 고정 --%> .pop-wrap .pop-btns{flex:none;} <%-- 버튼줄 항상 노출 --%> .pop-wrap .pop-grid{flex:1 1 0; min-height:0; display:block; overflow:hidden; overflow-y:auto;} <%-- 퍼블 CSS 가 없으므로 표 스킨을 값으로 직접(토큰 실측값) --%> .pop-wrap .pop-grid table{width:100%; border-collapse:collapse; table-layout:fixed;} .pop-wrap .pop-grid :is(th,td){padding:8px 6px; font-size:14px; border-bottom:1px solid #e0e0e0;} .pop-wrap .pop-grid thead th{position:sticky; top:0; z-index:2; background:#eef2f7; box-shadow:inset 0 1px 0 #1e2124, inset 0 -1px 0 #e0e0e0;} .pop-wrap .pop-grid caption{position:absolute; width:1px; height:1px; clip:rect(0,0,0,0);}

4. 실제로 겪은 함정 — 증상 → 원인

아래는 전부 다운로드 서비스 팝업 전환(2026.08)에서 실제로 하루씩 잡아먹은 것들입니다.

머리글이 본문과 같이 스크롤된다 → 스크롤러가 이다. 바깥(.modal-cont 등)이 스크롤되면 sticky 머리글은 그 안에서 같이 밀려 올라간다. 스크롤러는 반드시 하나. 머리글 위/뒤로 본문 행이 비친다 → ① sticky 요소에 배경이 없다(투명이면 그대로 통과한다) ② 스크롤포트에 padding-top 이 있다 — sticky 의 top:0 은 padding 안쪽 기준이라 그 padding 자리에 내용이 비친다. 스크롤러의 padding-top 은 0 으로. 머리글 위에 글자 한 줄이 비친다 → <caption> 이다. 퍼블·앱 base.css 는 caption 을 감추지만 윈도우 팝업 레이아웃은 그 CSS 를 안 불러서 실제로 그려진다. 스크롤하면 표 위쪽 선이 사라진다 → 퍼블은 그 선을 <table> 에 건다(common.css:867 + util.css:11 `.data-tbl table{border-top-width:1px}`). 표는 스크롤되는 쪽이라 같이 올라가 버린다. → 표의 것은 끄고(`> table{border-top-width:0}`) 스크롤 컨테이너에 border-top 을 건다. 컨테이너는 안 움직이니 늘 제자리다. 스크롤하면 머리글의 테두리만 사라진다 → border-collapse:collapse 에서 테두리는 에 속해 sticky 셀과 같이 안 움직인다. 머리글 선은 border 말고 box-shadow(inset) 로 그릴 것. 하단 버튼이 모달 바닥에 딱 붙는다 → 버튼줄(.modal-footer board-button)이 .modal-cont 밖(= .modal-body 직속)에 있다. 그래야 footer 로 고정된다. 안에 넣어야 `.modal-cont{padding:30px}`(common.css:948)을 받는다. 하단 버튼이 잘려 안 보인다 → 버튼줄이 스크롤 영역 에 있다. 버튼줄은 스크롤러 밖(flex:none). 브라우저를 좁히면 오른쪽 열이 통째로 사라진다 → 스크롤러가 `overflow:hidden; overflow-y:auto` 다(퍼블 셔틀 기본값). 가로가 넘치면 말없이 잘린다. → `overflow:auto` + 표에 `min-width` 를 주어 그 아래로는 가로 스크롤되게 한다. 체크박스가 칸 가운데로 안 온다 → 보이는 상자는 `label:before` 가 label 왼쪽 끝에 그린다(board.css:759~760). 래퍼(span)가 가운데여도 래퍼 안에 군더더기 폭이 있으면 상자만 왼쪽으로 밀린다. ⚠ 셀 padding(좌우 대칭)은 원인이 아니고, 래퍼에 flex 를 걸어도 안 통했다(실측). → label 에 직접 `display:block; width:18px; margin:0 auto`. 스크롤바가 아예 안 생긴다 / 표가 안 줄어든다 → flex 로 높이를 받는 구조에서 어느 단계의 min-height:0 이 빠졌거나 flex-basis 가 auto 다. 스크롤러에 height 를 직접 주면 이 부류가 통째로 사라진다. 표 스킨(테두리·머리글 배경)이 하나도 안 걸린다 → 래퍼 클래스에 '-tbl' 이 없거나, 래퍼와 <table> 사이에 div 가 끼어 있다. 퍼블 엔진 선택자가 `[class*="-tbl"] > table` 이라 직계 자식이어야 한다. 높이를 늘려도 목록이 안 늘어난다 (max-height 를 키워도 그대로) → 옛 CSS 가 height 고정값을 걸어 둔 것이다. max-height 는 height 를 이기지 못한다. dlService.css:442 .appfrom-box .data-table .scroll{height:180px} dlService.css:136 .scroll{height:503px} ← 스코프 없는 전역! → 내 규칙에 height:auto 를 함께 주어 고정값을 먼저 풀어야 max-height 가 의미를 갖는다. ⚠⚠ 클래스 이름만으로 옛 전역 CSS 가 딸려온다 (같은 계열 함정) → 흔한 단어를 옛 CSS 가 선점하고 있다. 새 마크업에 아래 이름을 쓰면 원치 않는 스타일이 붙는다. 'scroll' → dlService.css:136 .scroll{height:503px} '-tbl' 포함 → css/common.css:667~801 옛 표 엔진(굵은 검은 윗선 등) 'close' 포함 → 퍼블 .modal-body [class*='close'] → 우측 상단 X 자리로 절대배치 → 새로 만들 때는 이런 이름을 피하거나, 쓸 거면 무엇이 딸려오는지 확인하고 덮을 것. ⚠⚠ 윈도우 팝업에서 굵은 검은 윗선이 생기고, CSS 를 고쳐도 안 없어진다 → 클래스 이름에 '-tbl' 이 들어가서 앱 css/common.css:667~801 의 표 엔진에 걸린 것이다. (퍼블 것을 흉내 낸 앱 시절 버전이 아직 살아 있고, 팝업도 commonJs.jsp 로 이걸 로드한다) [class*="-tbl"] table{border-top:2px solid var(--gray-90)} ← 그 검은 선 [class*="-tbl"] * > tr{height:50px} · * > tr > *{padding:10px;font-size:16px} 선이 <table> 에 걸려 있어 스크롤하면 그 선만 사라지는 특징이 있다. → 퍼블 CSS 가 없는 윈도우 팝업에서 표 스킨을 직접 그릴 때는 클래스명에 '-tbl' 을 피할 것 (예: .pop-grid). 반대로 모달(퍼블 CSS 로드됨)에서는 '-tbl' 을 일부러 써서 퍼블 스킨을 탄다.
무엇이든 물어보세요