CSS&JS/⚡Thinkers

fixed thead(스크롤 할 때 부모 엘리먼트에 fix되는 thead를 만들고싶다면)

arancia_ 2021. 4. 14. 16:20

thead fixed top.zip
0.02MB

 

우선 소스코드 다운로드는 상단에서

 

 

참고 1) thead의 td와 th에 position:sticky;를 주는 방법 

velog.io/@drawyourmind/table-thead-%EA%B3%A0%EC%A0%95%EA%B3%BC-tbody-%EC%8A%A4%ED%81%AC%EB%A1%A4

 

table thead 고정과 tbody 스크롤

image HR시스템이 유난히 테이블과의 싸움이다. 그중 하나가 헤더 고정 이슈인데 이 한개가 아니고 colspan, rowspan으로 셀이 합쳐지면서 헤더가 고정되는 부분들이 있다보니 은근히 노가다 이슈

velog.io

장점 : CSS로만 해결 가능. 간단함
단점 : tr이 한줄이 아니라 2개 이상 될 땐 css로 일일히 설정해야한다. / IE 미지원

 

참고2) thead에 display:table; // thead의 tr에 display:table-row; // tbody에 display:block; height:고정값; overflow-y:auto; // tbody의 tr에 display:table;

stackoverflow.com/questions/62934011/fix-table-thead-in-ie11-while-maintaining-width

 

Fix table thead in IE11 while maintaining width

I have a table, and I want to fix the header on it, for Google Chrome, Firefox ... etc I use position: sticky, and it works perfectly without any issue. But in the hell of developers (Internet Expl...

stackoverflow.com

장점 : CSS로만 해결 가능. IE 지원
단점 : 보기만 해도 현기증나는 복잡함 / colgroup 무효로 인한 width 재노가다 작업 / 만일 colspan이나 rowspan이 발생한다면..?ㅎㅠㅠ

 

 

그리하여 만든 새로운 방법은 자바스크립트를 사용하여 thead를 자동으로 추가하고,
그 추가된 thead를 담고 있는 새로운 table은 position이 absolute이며
부모엘리먼트에서 스크롤시 그만큼 스크롤 되게끔 만들거다.
스크롤 할 때 새로 생성된 table은 top으로 움직여도 되고 transform으로 움직여도 되지만 브라우저 성능을 위해서 transform으로 움직이게 할꺼임
물론 난 쫌 친절하니까 top으로 움직이는것도 써놓긴 했음 (주석처리해놓음)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 1번 테이블 -->
<div class="부모엘리먼트">
    <table class="티헤드고정시킬테이블 테이블공통스타일">
        <thead></thead>
        <tbody></tbody>
    </table>
</div>
 
<!-- 2번 테이블 -->
<div class="부모엘리먼트">
    <table class="테이블공통스타일">
        <thead></thead>
        <tbody></tbody>
    </table>
</div>
cs

1번테이블과 2번테이블의 차이점은 "티헤드고정시킬테이블"이라는 스타일을 달아주면 자동적으로 스크립트에서 해당 테이블의 thead를 복사 생성하여 부모 엘리먼트에 붙여줄거다.

장점 : 후처리 스타일 노가다 작업을 할 필요가 없다! 우리가 이미 정적으로 만들어놓은것과 완벽하게 동일한게 또 추가되었을 뿐이니까!, 그리고 한 페이지 안에서 여러개의 테이블에 중복 적용 가능하다! 이 모든걸 클래스 하나만 추가한다면 ㅇㅇ

단점 : 스크립트 쓰기 귀찮지만 이정도야 스크립트라고 하기도 민망하지 

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<div class="myDiv">
    <table class="myTable makeFixed">
        <colgroup>
            <col style="width:10%;">
            <col style="width:20%;">
            <col style="width:30%;">
            <col style="width:40%;">
        </colgroup>
        <thead>
            <tr>
                <th>A</th> <th>B</th> <th>C</th> <th>D</th>
            </tr>
        </thead>
        <tbody>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
        </tbody>
    </table><!--myTable -->
</div><!-- myDiv -->
 
<div class="myDiv">
    <table class="myTable makeFixed">
        <colgroup>
            <col style="width:10%;">
            <col style="width:20%;">
            <col style="width:30%;">
            <col style="width:40%;">
        </colgroup>
        <thead>
            <tr>
                <th>A</th> <th>B</th> <th>C</th> <th>D</th>
            </tr>
        </thead>
        <tbody>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
        </tbody>
    </table><!--myTable -->
</div><!-- myDiv -->
 
<div class="myDiv">
    <table class="myTable">
        <colgroup>
            <col style="width:10%;">
            <col style="width:20%;">
            <col style="width:30%;">
            <col style="width:40%;">
        </colgroup>
        <thead>
            <tr>
                <th>A</th> <th>B</th> <th>C</th> <th>D</th>
            </tr>
        </thead>
        <tbody>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
            <tr> <td>001</td> <td>002</td> <td>003</td> <td>004</td> </tr>
        </tbody>
    </table><!--myTable -->
</div><!-- myDiv -->
cs

 

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*{margin:0;padding:0;box-sizing:border-box;}
html,body{
    background:#000;
}
 
table{table-layout:fixed; border-collapse:separate;border-spacing:0;width:100%;text-align:center;}
thead tr{background:#ccc;color:#666;}
th,td{padding:1rem;border:1px solid #000;}
 
.myDiv{
    position:relative; overflow-y:auto;
    margin:10rem auto;
    width: 80%; height:200px;
    background:#fff;}
 
table.fixed{
    position:absolute; z-index:10;
    top:0; left:0;
    width:100%;}
table.fixed thead tr{color:red;}
cs

 

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const makeFixed = document.getElementsByClassName('makeFixed');
let makeTable;
let thisColG, thisThead;
 
/* 동적으로 테이블 추가 */
for(let tbl of makeFixed){
    makeTable = document.createElement('TABLE');
    makeTable.setAttribute('class','fixed');
    thisColG = tbl.getElementsByTagName('COLGROUP')[0].cloneNode(true);
    thisThead = tbl.getElementsByTagName('THEAD')[0].cloneNode(true);
    makeTable.appendChild(thisColG);
    makeTable.appendChild(thisThead);
    tbl.parentElement.appendChild(makeTable);
}
 
/* 스크롤시 fixed 테이블은 상단에 계속 고정됨 */
const myDiv = document.getElementsByClassName('myDiv');
let thisFixed, nowScTop;
for(divs of myDiv){divs.addEventListener('scroll',theadFixed)}//
 
function theadFixed(){
    thisFixed = this.getElementsByClassName('fixed')[0];
    nowScTop = this.scrollTop;
    thisFixed.style.transform = `translateY(${nowScTop}px)`;
    // thisFixed.style.top = `${nowScTop}px`;
}//theadFixed
cs