순수한 CSS의 고정 헤더와 고정 열이있는 테이블


100

고정 된 머리글과 고정 된 첫 번째 열이있는 html 테이블 (또는 비슷한 모양)을 만들어야합니다.

지금까지 본 모든 솔루션은 Javascript를 사용하거나 jQueryscrollTop / scrollLeft를 설정하지만 모바일 브라우저에서는 원활하게 작동하지 않으므로 순수한 CSS 솔루션을 찾고 있습니다.

여기에서 고정 열에 대한 해결책을 찾았습니다. jsfiddle.net/C8Dtf/20/ 하지만 난 너무 고정 된 헤더를 만들을 향상시킬 수있는 방법을 모르겠어요.

웹킷 브라우저에서 작동하거나 일부 css3기능을 사용하고 싶지만 반복합니다. 사용하고 싶지 않습니다.Javascript 합니다. 스크롤 .

편집 : 이것은 내가 달성하려는 동작의 예입니다 : https://web.archive.org/web/20130829032141/http://datatables.net/release-datatables/extras/FixedColumns/css_size.html


고정 헤더가있는 <html> <table> <thead>가 당분간 css-level-3과 관련이 있는지 모르겠습니다. 당신은 또 무엇을 가지고 있습니까? 지금까지 뭐 해봤 어 ?
Milche Patern 2013

복잡한 position동작을 행과 셀 에 적용하려고 시도했지만 적용 가능한지 여부를 잘 모르겠습니다.
panfil

2
이 답변이 도움이 될 수 stackoverflow.com/questions/14834198/...
게리

답변:


146

고정 헤더 행과 첫 번째 열이있는 실제 순수 CSS 솔루션

순수한 CSS를 사용하여 고정 된 헤더와 고정 된 첫 번째 열이 모두있는 테이블을 만들어야했는데 여기에 내가 원하는 답변은 없었습니다.

position: sticky속성은 Chrome, Firefox 및 Edge의 최신 버전에서 상단 (가장 많이 사용했듯이)과 측면을 모두 지원합니다. 이것은와 결합 될 수 div를 가지overflow: scroll 페이지의 어느 곳에 나 배치 할 수있는 고정 헤더가있는 테이블을 제공 속성 할 수 있습니다.

테이블을 컨테이너에 넣으십시오.

<div class="container">
  <table></table>
</div>

사용 overflow: scroll스크롤 수 있도록 컨테이너를에 :

div.container {
  overflow: scroll;
}

그마는 의견에서 지적, 용기도 필요 max-width하고를 max-height.

사용 position: sticky가장자리에 테이블 셀을 가지고 스틱과 top, right또는 left스틱에있는 가장자리를 선택합니다 :

thead th {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;
}

tbody th {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  left: 0;
}

MarredCheese 코멘트에서 언급 한 첫 번째 열이 포함되어있는 경우, <td>대신의 요소 <th>요소를, 당신은 사용할 수 있습니다tbody td:first-child 당신의 CSS 대신의tbody th

첫 번째 열의 헤더를 왼쪽에 고정하려면 다음을 사용하세요.

thead th:first-child {
  left: 0;
  z-index: 1;
}

https://jsfiddle.net/qwubvg9m/1/


22
이것이 가장 좋은 대답 인 것 같습니다.
user1190132

9
@PirateApp은 당신이 알고있는 경우 width첫 번째 열의, 당신이 사용할 수있는 position: sticky로모그래퍼 두 번째 열에서 셀에 left값 첫 번째 열의에 동일 width: jsfiddle.net/wvypo83c/794
마태 복음 Schlachter

4
이 대답은 맨 아래까지 읽는 것이 가치가 있음을 증명합니다!
mlerley

4
컨테이너에 최대 너비 및 최대 높이를 설정하지 않으면 작동하지 않습니다.
Dagmar

9
이 답변은 여기 SO와 웹에서 놀랍게도 당황 스러울 정도로 찬성 된 포스터로부터 오작동하고 복잡하며 시간을 낭비하는 끝없는 답변의 바다를 통해 우리를 안내하는 등대입니다. 첫 번째 열에 <td>요소 대신 <th>요소 가 포함되어있는 경우 tbody td:first-childCSS에서 tbody th.
MarredCheese 19

33

요즘이 가능 하여 달성하기 위해 단지 CSS를 가진 position: sticky속성입니다.

다음은 스 니펫입니다.

(jsFiddle : https://jsfiddle.net/hbqzdzdt/5/ )

.grid-container {
  display: grid; /* This is a (hacky) way to make the .grid element size to fit its content */
  overflow: auto;
  height: 300px;
  width: 600px;
}
.grid {
  display: flex;
  flex-wrap: nowrap;
}
.grid-col {
  width: 150px;
  min-width: 150px;
}

.grid-item--header {
  height: 100px;
  min-height: 100px;
  position: sticky;
  position: -webkit-sticky;
  background: white;
  top: 0;
}

.grid-col--fixed-left {
  position: sticky;
  left: 0;
  z-index: 9998;
  background: white;
}
.grid-col--fixed-right {
  position: sticky;
  right: 0;
  z-index: 9998;
  background: white;
}

.grid-item {
  height: 50px;
  border: 1px solid gray;
}
<div class="grid-container">
  <div class="grid">
    <div class="grid-col grid-col--fixed-left">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col grid-col--fixed-right">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
    </div>

  </div>
</div>

호환성에 관해서. 모든 주요 브라우저에서 작동하지만 IE에서는 작동하지 않습니다. polyfill이 position: sticky있지만 시도한 적이 없습니다.


2
이것은 훌륭합니다, 그것을 사랑하십시오!
캡틴 Lu

3
<div>가 아닌 <table> -tags를 사용하여이를 달성하는 방법
Andreas

1
응용 프로그램을 개발 중이고이 테이블을 인쇄하기 위해 레코드를 반복해야하는 경우 성능이 좋지 않을 것이라고 생각합니다. 테이블의 모든 열에 대해 전체 레코드 배열을 반복해야하기 때문입니다. 이 HTML은 열 단위로 작동합니다.
igasparetto

@igasparetto 실제로 행 / 열을 다른 방식으로 정렬 할 수 있으며 솔루션은 여전히 ​​작동합니다. 나중에 시간이 있으면 그리드 정렬 된 행-> 열로 스 니펫을 만들 수 있습니다.
Alvaro

2
<table> 및 관련 태그를 사용하지 않고 표 형식 데이터를 표시하지 않는 것이 좋습니다. 접근성을 포함하여 이러한 방식으로 HTML의 의도 된 사용을 중단하는 데는 몇 가지 문제가 있습니다. 참조 : w3.org/WAI/tutorials/tables
Ben Morris

15

이것은 쉬운 일이 아닙니다.

다음 링크는 작동하는 데모에 대한 것입니다.

lanoxx의 의견에 따라 업데이트 된 링크

http://jsfiddle.net/C8Dtf/366/

다음을 추가하는 것을 잊지 마십시오.

<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js"></script>
<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/extras/FixedColumns/media/js/FixedColumns.js"></script>

나는 이것을 달성하는 다른 방법을 보지 못합니다. 특히 CSS 만 사용하는 것은 아닙니다.

이것은 겪을 것이 많습니다. 도움이 되었기를 바랍니다 :)


필터 사용을 전환하려면 : "bFilter": false
lanoxx 2013 년

6
이다 에만 CSS로이를 달성 할 수. 쉽지는 않지만 가능합니다.
Jimmy T.

약 10 개의 솔루션 중에서 이것이 유일한 솔루션이었습니다. BTW은 "57 (57)의 항목 표시 1"추가 제거하는 "bInfo" : false.dataTable()전화
hansaplast

datatables == "최고"
billynoah

이 솔루션이 나쁘기 때문에 반대표를 던집니다. 은 thead변화에 바인딩되지 않은 자신의 테이블에 td셀 텍스트가 긴 경우 그래서, 요소 th폭이 그에 따라 조정되지 않습니다.
vsync

14

이러한 제안은 모두 훌륭하지만 모두가 아니라 머리글이나 열 중 하나만 수정하거나 자바 스크립트를 사용하고 있습니다. 그 이유는 순수한 CSS로 할 수 있다고 믿지 않습니다. 이유:

가능하다면 여러 스크롤 가능한 div를 서로 다른 방향으로 스크롤하는 여러 개의 스크롤 가능한 div를 서로 중첩해야합니다. 그런 다음 테이블을 고정 헤더, 고정 열 및 나머지 데이터의 세 부분으로 분할해야합니다.

좋아. 하지만 이제 문제는 스크롤 할 때 둘 중 하나를 그대로 두도록 할 수 있지만 다른 하나는 첫 번째 스크롤 영역 안에 중첩되어 있으므로 눈에 띄지 않게 스크롤 될 수 있으므로 제자리에 고정 할 수 없습니다. 화면. '아하'당신은 '하지만 나는 그것을하기 위해 어떻게 든 절대 또는 고정 된 위치를 사용할 수있다'라고 말한다-당신은 할 수 없다. 그렇게하면 해당 컨테이너를 스크롤 할 수 없게됩니다. 그것은 닭고기와 달걀의 상황입니다. 둘 다 가질 수는 없으며 서로를 취소합니다.

유일한 해결책은 자바 스크립트를 통하는 것입니다. 세 가지 요소를 완전히 분리하고 자바 스크립트를 통해 위치를 동기화해야합니다. 이 페이지의 다른 게시물에 좋은 예가 있습니다. 이것은 또한 볼 가치가 있습니다.

http://tympanus.net/codrops/2014/01/09/sticky-table-headers-columns/


9

jsfiddle에서 약간 변경했습니다. 이것은 당신이하려는 것일 수 있습니다.

http://jsfiddle.net/C8Dtf/81/

다음과 같이 제목을 하드 코딩했습니다.

<table id="left_table" class="freeze_table">
    <tr class='tblTitle'>
         <th>Title 1</th>
         <th>Title 2</th>
    </tr>
</table>

그리고 몇 가지 스타일도 추가했습니다.

.tblTitle{
   position:absolute;
    top:0px;
    margin-bottom:30px;
    background:lightblue;
}
td, th{
    padding:5px;
    height:40px;
    width:40px;
    font-size:14px;
}

이것이 당신이 원하는 것입니다 :)


1
내용과 함께 스크롤하려면 오른쪽 테이블의 헤더가 필요합니다.
panfil 2013-04-04

URL은 다음과 같습니다 : jsfiddle.net/C8Dtf/84 . 두 테이블을 정렬하려면 오른쪽 테이블의 스타일을 조정하기 만하면됩니다.
Phillip-juan

아뇨. 당신은 잘 이해하지 못합니다. 오른쪽 테이블의 머리글을 맨 위에 고정해야 테이블이 위아래로 스크롤 될 때 여전히 표시되지만 테이블이 오른쪽 또는 왼쪽으로 스크롤 될 때 머리글은 오른쪽 또는 왼쪽으로 스크롤해야하지만 여전히 맨 위에 고정되어 있어야합니다. 저의 영어 실력이 나빠서 죄송합니다.
panfil 2013

그렇다면 오른쪽 테이블의 머리글이 세로로 스크롤 할 때 고정되고 가로로 스크롤 될 때 스크롤되기를 원합니까?
Phillip-juan

다음은 내가 달성하고자하는 동작의 예입니다. datatables.net/release-datatables/extras/FixedColumns/…
panfil

9

CSS 만 사용하는 예 :

.table {
  table-layout: fixed;
  width: 500px;
  border-collapse: collapse;
}

.header th {
  font-family: Calibri;
  font-size: small;
  font-weight: lighter;
  border-left: 1px solid #000;
  background: #d0d0d0;
}

.body_panel {
  display: inline-block;
  width: 520px;
  height: 300px;
  overflow-y: scroll;
}

.body tr {
  border-bottom: 1px solid #d0d0d0;
}

.body td {
  border-left: 1px solid #d0d0d0;
  padding-left: 3px;
  font-family: Calibri;
  font-size: small;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
<body>

  <table class="table">

    <thead class="header">

      <tr>
        <th style="width:20%;">teste</th>
        <th style="width:30%;">teste 2</th>
        <th style="width:50%;">teste 3</th>
      </tr>

    </thead>
  </table>

  <div class="body_panel">

    <table class="table">
      <tbody class="body">

        <tr>
          <td style="width:20%;">asbkj k kajsb ksb kabkb</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

      </tbody>
    </table>

  </div>

</body>


3
나는 heder 고정뿐만 아니라 첫 번째 열도 필요했습니다.
panfil

이 예는 html에서 두 개의 테이블을 사용하는 방법을 보여줍니다. 하나의 테이블은 헤더 만 렌더링합니다. 두 번째 테이블은 행만 렌더링하지만 div. div헤더가 같은 위치에있는 동안 행 스크롤을 허용하는 것은 입니다. 이 접근 방식은 내 필요에 맞았습니다.
David Tansey

가로 스크롤도있는 경우 테이블의 스크롤 위치를 동기화하려면 JS가 필요합니다.
Zoltán Tamási

4

문제에 대한 Paul O'Brien의 훌륭한 솔루션을 찾았으며 링크를 공유하고 싶습니다 : https://codepen.io/paulobrien/pen/LBrMxa

바닥 글 스타일을 제거했습니다.

html {
  box-sizing: border-box;
}
*,
*:before,
*:after {
  box-sizing: inherit;
}
.intro {
  max-width: 1280px;
  margin: 1em auto;
}
.table-scroll {
  position: relative;
  width:100%;
  z-index: 1;
  margin: auto;
  overflow: auto;
  height: 350px;
}
.table-scroll table {
  width: 100%;
  min-width: 1280px;
  margin: auto;
  border-collapse: separate;
  border-spacing: 0;
}
.table-wrap {
  position: relative;
}
.table-scroll th,
.table-scroll td {
  padding: 5px 10px;
  border: 1px solid #000;
}
.table-scroll thead th {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}

th:first-child {
  position: -webkit-sticky;
  position: sticky;
  left: 0;
  z-index: 2;
  background: #ccc;
}
thead th:first-child {
  z-index: 5;
}

4

헤더와 열을 모두 수정하려면 다음 플러그인을 사용할 수 있습니다.


2019 년 7 월 업데이트

최근에는 각 항목 (부모 컨테이너 대신 )에 적용된 CSS 속성 ( 자세한 내용은 여기) 을 기반으로 하는 순수한 CSS 솔루션 도 등장 했습니다.position: sticky;TH


1
첫 번째 링크가 끊어졌습니다. 두 번째는 jQuery를 사용합니다.
PussInBoots dec

데드 링크 제거에 대한 답변 업데이트
Luca Detomi 19

2

최근에 고정 된 헤더 그룹과 고정 된 첫 번째 열이있는 솔루션을 만들어야했습니다. 내 테이블을 div로 분할하고 jquery를 사용하여 창 스크롤을 캡처했습니다.

http://jsfiddle.net/TinT/EzXub/2346/

var prevTop = 0;
var prevLeft = 0;

$(window).scroll(function(event){
  var currentTop = $(this).scrollTop();
  var currentLeft = $(this).scrollLeft();

  if(prevLeft !== currentLeft) {
    prevLeft = currentLeft;
    $('.header').css({'left': -$(this).scrollLeft()})
  }
  if(prevTop !== currentTop) {
    prevTop = currentTop;
    $('.leftCol').css({'top': -$(this).scrollTop() + 40})
  }
});

1

동료와 저는 고정 헤더로 테이블을 장식하는 데 사용할 수있는 Angular 지시문을 제공하는 새로운 GitHub 프로젝트를 방금 출시했습니다. https://github.com/objectcomputing/FixedHeader

일부 div를 추가하는 지시문과 함께 css 및 angular에만 의존합니다. jQuery가 필요하지 않습니다.

이 구현은 다른 구현만큼 완전한 기능을 갖추고 있지는 않지만 단순히 고정 테이블을 추가하는 것이 필요하다면 이것이 좋은 옵션 일 수 있다고 생각합니다.


1

Internet Explorer 9 + Chrome + Firefox (Windows) 및 Safari (Mac)와 이틀 간의 싸움을 한 후

  • 이 모든 브라우저와 호환
  • 자바 스크립트를 사용하지 않고
  • une div와 하나의 테이블 만 사용
  • 스크롤 가능한 본문이있는 고정 머리글 및 바닥 글 (IE 제외). 열 너비가 동일한 헤더 및 본문

결과: 여기에 이미지 설명 입력

HTML :

  <thead>
    <tr>
      <th class="nombre"><%= f.label :cost_center %></th>
      <th class="cabecera cc">Personal</th>
      <th class="cabecera cc">Dpto</th>
    </tr>
  </thead>
  <tbody>
    <% @cost_centers.each do |cc| %>
    <tr>
      <td class="nombre"><%= cc.nombre_corto %></td>
      <td class="cc"><%= cc.cacentrocoste %></td>
      <td class="cc"><%= cc.cacentrocoste_dpto %></td>
    </tr>
    <% end %>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="3"><a href="#">Mostrar mas usuarios</a></td>
    </tr>
  </tfoot>
</table>

CSS :

div.cost_center{
  width:320px;
  font-size:75%;
  margin-left:5px;
  margin-top:5px;
  margin-bottom: 2px;
  float: right;
  display: inline-block;
  overflow-y: auto;
  overflow-x: hidden;
  max-height:300px;  
}

div.cost_center label { 
  float:none;
  font-size:14px;
}

div.cost_center table{
  width:300px;
  border-collapse: collapse; 
  float:right;
  table-layout:fixed;
}

div.cost_center table tr{
  height:16px;
}
div.cost_center th{
  font-weight:normal;
}

div.cost_center table tbody{
  display: block;
  overflow: auto;
  max-height:240px;
}

div.cost_center table thead{
  display:block;
}

div.cost_center table tfoot{
  display:block;
}
div.cost_center table tfoot td{
  width:280px;
}
div.cost_center .cc{
  width:60px;
  text-align: center; 
  border: 1px solid #999;
}

div.cost_center .nombre{
  width:150px;
}
div.cost_center tbody .nombre{
  border: 1px solid #999;
}

div.cost_center table tfoot td{
 text-align:center;  
 border: 1px solid #999; 
} 

div.cost_center table th, 
div.cost_center table td { 
  padding: 2px;
  vertical-align: middle; 
}

div.cost_center table tbody td {
  white-space: normal;
  font:  .8em/1.4em Verdana, sans-serif;
  color: #000;
  background-color: white;
}
div.cost_center table th.cabecera { 
  font:  0.8em/1.4em Verdana, sans-serif;
  color: #000;
  background-color: #FFEAB5;
}

좋은 시도지만 나에게 너무 잘 작동하지 않습니다. 이 예제 ( jsfiddle.net/5ka6e )에서 헤더의 크기가 올바르게 조정되지 않습니다. 이러한 종류의 오류는 결국 데이터와 헤더가 일치하지 않게 될 수 있습니다.
darkzangel 2014

1
추가하는 것을 잊고 div.cost_center table{border-collapse: collapse;}세 번째 캡션은 60px 이내 여야합니다 (이 예에서)
Albert Català 2014

1

기존 답변은 대부분의 사람들에게 적합하지만 고정 헤더와 첫 번째 (고정) 열의 오른쪽에 그림자 를 추가하려는 사람들을 위해 다음과 같은 작업 예제 (순수 CSS)가 있습니다.

http://jsbin.com/nayifepaxo/1/edit?html,output

일이 점점의 주요 트릭을 사용하는 ::after최초의 각각의 오른쪽에 그림자를 추가 할 tdtr:

tr td:first-child:after {
  box-shadow: 15px 0 15px -15px rgba(0, 0, 0, 0.05) inset;
  content: "";
  position:absolute;
  top:0;
  bottom:0;
  right:-15px;
  width:15px;
}

모든 작업을 수행하는 데 시간이 오래 걸렸기 때문에 비슷한 상황에있는 사람들과 공유 할 것이라고 생각했습니다.


다른 사람의 대답을 바탕으로 그림자를 추가 했습니까?
PussInBoots dec

1

머리글 바닥 글 수정 필요


0

이와 같은 방법이 효과가있을 수 있습니다. 헤더 행의 열 너비를 설정해야 할 것입니다.

thead { 
    position: fixed;
}

http://jsfiddle.net/vkhNC/

최신 정보:

나는 당신이 준 예제가 CSS만으로 가능하다고 확신하지 않습니다. 나는 누군가가 나를 틀렸다는 것을 증명하기를 원합니다. 여기 내가 지금까지 가지고있는 것 입니다. 완성 된 제품은 아니지만 시작이 될 수 있습니다. 이것이 도움이되는 방향으로 여러분을 안내하기를 바랍니다.


헤더뿐만 아니라 첫 번째 열도 수정해야합니다.
panfil

5
문제는 헤더의 너비가 느슨하다는 것입니다. 다른 헤더 열 크기와 데이터 열 크기로보기 흉해 보입니다.
Akash Kava

0

또 다른 해결책은 AngularJS를 사용하는 것입니다. AngularUI 모듈에는 ng-grid열 고정이라는 기능을 지원하는 라는 지시문이 있습니다. 100 % 순수한 CSS는 아니지만 다른 솔루션도 마찬가지입니다.

http://angular-ui.github.io/ng-grid/#columnPinning


0

순수한 CSS 예 :

<div id="cntnr">
    <div class="tableHeader">
        <table class="table-header table table-striped table-bordered">
            <thead>
                <tr>
                    <th>this</th>
                    <th>transmission</th>
                    <th>is</th>
                    <th>coming</th>
                    <th>to</th>
                    <th>you</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                </tr>
            </tbody>
        </table>
    </div>


    <div class="tableBody">
        <table class="table-body table table-striped table-bordered">
            <thead>
                <tr>
                    <th>this</th>
                    <th>transmission</th>
                    <th>is</th>
                    <th>coming</th>
                    <th>to</th>
                    <th>you</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                </tr>
            </tbody>
        </table>
    </div>

</div>

#cntnr {
    width: auto;
    height: 200px;
    border: solid 1px #444;
    overflow: auto;
}

.tableHeader {
    position: fixed;
    height: 40px;
    overflow: hidden;
    margin-right: 18px;
    background: white;
}

.table-header tbody {
    height: 0;
    visibility: hidden;
}

.table-body thead {
    height: 0;
    visibility: hidden;
}

http://jsfiddle.net/cCarlson/L98m854d/

단점 : 고정 헤더 구조 / 로직은 특정 차원에 상당히 의존하므로 추상화는 실행 가능한 옵션이 아닐 수 있습니다 .


고정 헤더와 고정 첫 번째 열이 모두 필요합니다.
panfil 2014

아 ... 이걸 지적 해주셔서 감사합니다, 팬필. 편집하겠습니다. Cheers
Cody

0

위치 : 고정은 크롬의 (thead)와 같은 일부 요소와 사파리와 같은 다른 웹킷 브라우저에서는 작동하지 않습니다.

하지만 (th)와 잘 작동합니다.

body {
  background-color: rgba(0, 255, 200, 0.1);
}

.intro {
  color: rgb(228, 23, 23);
}

.wrapper {
  overflow-y: scroll;
  height: 300px;
}

.sticky {
  position: sticky;
  top: 0;
  color: black;
  background-color: white;
}
<div class="container intro">
  <h1>Sticky Table Header</h1>
  <p>Postion : sticky doesn't work for some elements like (thead) in chrome and other webkit browsers like safari. </p>
  <p>But it works fine with (th)</p>
</div>
<div class="container wrapper">
  <table class="table table-striped">
    <thead>
      <tr>
        <th class="sticky">Firstname</th>
        <th class="sticky">Lastname</th>
        <th class="sticky">Email</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>James</td>
        <td>Vince</td>
        <td>james@example.com</td>
      </tr>
      <tr>
        <td>Jonny</td>
        <td>Bairstow</td>
        <td>jonny@example.com</td>
      </tr>
      <tr>
        <td>James</td>
        <td>Anderson</td>
        <td>james@example.com</td>
      </tr>
      <tr>
        <td>Stuart</td>
        <td>Broad</td>
        <td>stuart@example.com</td>
      </tr>
      <tr>
        <td>Eoin</td>
        <td>Morgan</td>
        <td>eoin@example.com</td>
      </tr>
      <tr>
        <td>Joe</td>
        <td>Root</td>
        <td>joe@example.com</td>
      </tr>
      <tr>
        <td>Chris</td>
        <td>Woakes</td>
        <td>chris@example.com</td>
      </tr>
      <tr>
        <td>Liam</td>
        <td>PLunkett</td>
        <td>liam@example.com</td>
      </tr>
      <tr>
        <td>Jason</td>
        <td>Roy</td>
        <td>jason@example.com</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Hales</td>
        <td>alex@example.com</td>
      </tr>
      <tr>
        <td>Jos</td>
        <td>Buttler</td>
        <td>jos@example.com</td>
      </tr>
      <tr>
        <td>Ben</td>
        <td>Stokes</td>
        <td>ben@example.com</td>
      </tr>
      <tr>
        <td>Jofra</td>
        <td>Archer</td>
        <td>jofra@example.com</td>
      </tr>
      <tr>
        <td>Mitchell</td>
        <td>Starc</td>
        <td>mitchell@example.com</td>
      </tr>
      <tr>
        <td>Aaron</td>
        <td>Finch</td>
        <td>aaron@example.com</td>
      </tr>
      <tr>
        <td>David</td>
        <td>Warner</td>
        <td>david@example.com</td>
      </tr>
      <tr>
        <td>Steve</td>
        <td>Smith</td>
        <td>steve@example.com</td>
      </tr>
      <tr>
        <td>Glenn</td>
        <td>Maxwell</td>
        <td>glenn@example.com</td>
      </tr>
      <tr>
        <td>Marcus</td>
        <td>Stoinis</td>
        <td>marcus@example.com</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Carey</td>
        <td>alex@example.com</td>
      </tr>
      <tr>
        <td>Nathan</td>
        <td>Coulter Nile</td>
        <td>nathan@example.com</td>
      </tr>
      <tr>
        <td>Pat</td>
        <td>Cummins</td>
        <td>pat@example.com</td>
      </tr>
      <tr>
        <td>Adam</td>
        <td>Zampa</td>
        <td>zampa@example.com</td>
      </tr>
    </tbody>
  </table>
</div>

또는 내 코드 펜 예제를 방문하십시오 .


-1

나는 이것이 당신을 도울 것이라고 생각합니다 : https://datatables.net/release-datatables/extensions/FixedHeader/examples/header_footer.html

간단히 말해서 dataTable을 만드는 방법을 알고 있다면이 jQuery 줄을 하단에 추가하기 만하면됩니다.

$(document).ready(function() {
    var table = $('#example').DataTable();

    new $.fn.dataTable.FixedHeader( table, {
        bottom: true
    } );
} );

bottom : true // Bottom 헤더도 고정합니다.


-2

순수한 HTML과 CSS 만 사용하려는 경우 문제에 대한 해결책이 있습니다
.이 jsFiddle 에서 고정 헤더가있는 테이블을 제공하는 비 스크립트 솔루션을 볼 수 있습니다. 고정 된 첫 번째 열에 대한 마크 업을 조정하는 것도 문제가되지 않습니다. hWrapper-div 내부의 첫 번째 열에 대해 절대 위치 테이블을 만들고 -div 위치를 변경하기 vWrapper만하면됩니다.
동적 콘텐츠를 제공하는 것은 서버 측 또는 브라우저 측 유혹 엔진을 사용하는 데 문제가되지 않아야합니다. 내 솔루션은 IE8 이후의 모든 최신 브라우저와 이전 브라우저에서 잘 작동합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.