Исправить заголовки столбцов при горизонтальной прокрутке

Я пытаюсь исправить заголовки столбцов, чтобы я мог прокручивать по горизонтали и все же видеть заголовки. Я пробовал следующее, но, похоже, не работает. Если вы видите на скриншотах, если я перемещаю экран вверх или вниз, кажется, что заголовки не остаются на одном месте и происходит неправильное перекрытие. Первый td всегда скрыт за th.

скриншот 1Исправить заголовки столбцов при горизонтальной прокрутке

скриншот 2 Исправить заголовки столбцов при горизонтальной прокрутке

   th:first-child {
        position: fixed;

    } 

        th {
            position: fixed;
        }
.fixed-side {
    border:1px solid #000;
    background:#eee;
    visibility:visible;
}

CSS

<style>
    th,
    td {
        padding: 7px;
        min-width: 300px;
        max-width: 300px;
    }

    /* th:first-child {
    position: fixed;

} */


    th {
        position: fixed;
    }

    .fundClassesTable {

        table-layout: fixed;
    }


    .cellbgcolor {
        color: transparent;
    }

    .btn {}

    .tableItem {
        text-align: left;
        border-left: solid 1px lightgrey;
        border-top: solid 1px lightgrey;
        border-right: solid 1px lightgrey;
        border-bottom: solid 1px lightgrey;

    }

    .rowItem:hover {
        background-color: #f5f7f7;
    }


    label {
        margin-left: 0.5rem;
        vertical-align: middle
    }


    .panel-heading {
        color: black;
        border-color: #ddd;
        overflow: hidden;
        padding-top: 5px !important;
        padding-bottom: 5px !important;
    }

    .panel-heading .left-label {
        display: inline-block;
        padding-top: 5px !important;

    }

    .scrollClass {
        overflow-x: scroll;
        display: grid;

    }

    .panel-heading label {
        margin-bottom: 0px !important;
    }

    #FundClass tr:hover {
        background-color: #ECF0F1;
    }

    .headcol {
        position: absolute;
        min-width: 300px;
        max-width: 300px;
        width: 5em;
        left: 0;
        top: auto;
        border-top-width: 1px;
        /*only relevant for first row*/
        margin-top: -1px;
        /*compensate for top border*/
    }

    .headcol:before {
        content: 'Row ';
    }

    .collapsed {
    color: #d6630a;
    font-size: 22px;
    text-decoration: none;
    font-weight: bold;
}

.expanded {
    color: #d6630a;
    font-size: 22px;
    text-decoration: none;
    font-weight: bold;

}

.fixed-side {
    border:1px solid #000;
    background:#eee;
    visibility:visible;
}

</style>

HTML

<div class = "card">
    <div class = "card-header panel-heading">
        <span class = "left-label" style = "font-size: 18px; font-weight: bold; ">Fund Classes</span>

        <a class = "pull-right" [ngClass] = "{'collapsed': !isExpanded, 'expanded': isExpanded }" data-toggle = "collapse"
            href = "javascript:void(0);" (click) = "expand()" role = "button" [attr.aria-expanded] = "isExpanded"
            aria-controls = "fundClass"> {{ isExpanded ? '-' : '+' }}
        </a>

        <div *ngIf = "CanEdit" class = "pull-right"
            style = "padding-right:10px; display: inline-block; vertical-align:middle">
            <button style = "text-align: center; vertical-align:middle" class = "btn btn-default pull-right"
                (click) = "openFundClassModal()"> <i data-bind = "visible: true" class = "fa fa-plus-square"></i> Add
                Class</button>
        </div>
        <div class = "pull-right" style = "padding-right:10px; display: inline-block; vertical-align:middle">
            <label style = "text-align: center; vertical-align:middle" class = "btn btn-primary"
                [ngClass] = "{'btn-primary': InvestedOnly, 'btn-default': !InvestedOnly }"><input type = "checkbox"
                    (click) = "isInvestedSelected($event)" checked = "checked" [(ngModel)] = "InvestedOnly" class = "hidden"
                    for = "chkInvested" />Invested Only</label>
        </div>
    </div>


    <div *ngIf = "!FundClasses || !FundClasses.FundDetailsViewModel" style = "padding-top:10px">
        <div class = "alert alert-warning" style = "text-align:center" role = "alert">
            Loading... Please Wait
        </div>
    </div>
    <div [ngClass] = "{'show': isExpanded}" id = "fundClass" class = "collapse" role = "tabpanel" aria-labelledby = "fundClass_heading"
        data-parent = "#fundClass" [attr.aria-expanded] = "isExpanded">
        <div class = "card-body scrollClass" *ngIf = "FundClasses && FundClasses.FundDetailsViewModel">

            <table id = "FundClass" class = "fundClassesTable table-striped">
                <!-- *ngIf = "c != 'Buttons1'  && !CanEdit" -->
                <tr *ngFor = "let c of FundClasses.FundClassColumnNames">
                    <th class = "fixed-side" scope = "col" [ngClass] = "c != 'Buttons1'? 'tableItem bold' : 'tableItem cellbgcolor'"> {{ c }}</th>

                    <ng-container *ngFor = "let fundClass of FundClasses.FundDetailsViewModel let i=index">
                        <ng-container *ngFor = "let f of fundClass['FundClassDetailsViewModel'] | keyvalue">

                            <td class = "tableItem" style = "font-weight: bold" *ngIf = "c == 'Fund Name'">
                                {{ f.value.FundName}}
                            </td>
                            <td [attr.id] = "'f.value.Id'" class = "tableItem"
                                *ngIf = "!EditMode[f.value.Id] && c == 'Accounting Class Name'">{{ f.value.Description}}
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "EditMode[f.value.Id] && c == 'Accounting Class Name'"
                                class = "tableItem">
                                <input kendoTextBox [(ngModel)] = "f.value.Description"
                                    style = "width: 284px; height: 29.5px;" />
                            </td>
                            <td class = "tableItem" *ngIf = "c == 'Class ID'">{{f.value.Id}}</td>
                            <td *ngIf = "EditMode[f.value.Id] && c == 'Legal Fund Class'" class = "tableItem">
                                <kendo-dropdownlist [(ngModel)] = "f.value.LegalFundClassId"
                                    class = "form-control  form-control-sm " [data] = "fundClass.PrimaryLegalFundClasses"
                                    [filterable] = "false" textField = "Description" [valuePrimitive] = "true"
                                    valueField = "Id">
                                </kendo-dropdownlist>
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "!EditMode[f.value.Id] && c == 'Legal Fund Class'"
                                class = "tableItem">
                                {{ f.value.LegalFundClassName}}
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "EditMode[f.value.Id] && c == 'Inception Date'"
                                class = "tableItem">
                                <kendo-datepicker [format] = "'MMM dd, yyyy'" [(ngModel)] = "f.value.InceptionDate"
                                    class = "form-control  form-control-sm">
                                </kendo-datepicker>
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "!EditMode[f.value.Id] && c == 'Inception Date'"
                                class = "tableItem">
                                {{ f.value.InceptionDate | date:"'MMM dd, yyyy"}}
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "EditMode[f.value.Id] && c == 'Invested Amount'"
                                class = "tableItem">
                                <input kendoTextBox [(ngModel)] = "f.value.InvestedAmount"
                                    style = "width: 284px; height: 29.5px;" />
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "!EditMode[f.value.Id] && c == 'Invested Amount'"
                                class = "tableItem">
                                {{ f.value.InvestedAmount | number : '.2-2'}}
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "EditMode[f.value.Id] && c == 'Vehicle Type'"
                                class = "tableItem">
                                <kendo-dropdownlist [(ngModel)] = "f.value.VehicleTypeId"
                                    class = "form-control  form-control-sm " [data] = "FundClasses.VehicleTypes"
                                    [filterable] = "false" textField = "Name" [valuePrimitive] = "true" valueField = "Id">
                                </kendo-dropdownlist>
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "!EditMode[f.value.Id] && c == 'Vehicle Type'"
                                class = "tableItem">
                                {{ f.value.VehicleTypeName}}
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "EditMode[f.value.Id] && c == 'Closure Status'"
                                class = "tableItem">
                                <kendo-dropdownlist [(ngModel)] = "f.value.ClosureStatusId"
                                    class = "form-control  form-control-sm" [data] = "FundClasses.ClosureStatuses"
                                    [filterable] = "false" textField = "Name" [valuePrimitive] = "true" valueField = "Id">
                                </kendo-dropdownlist>
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "!EditMode[f.value.Id] && c == 'Closure Status'"
                                class = "tableItem">
                                {{ f.value.ClosureStatusName}}
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "EditMode[f.value.Id] && c == 'Is Side Pocket?'"
                                class = "tableItem">
                                <input type = "checkbox" value = "{{f.value.IsSidePocket}}" id = "chkSidePocket"
                                    [(ngModel)] = "f.value.IsSidePocket" style = "width: 13px; height: 13px;" />
                                <label for = "chk">Yes</label>

                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "!EditMode[f.value.Id] && c == 'Is Side Pocket?'"
                                class = "tableItem">
                                {{ f.value.IsSidePocket == true ? 'Yes' : 'No'}}
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "EditMode[f.value.Id] && c == 'Is Thematic?'"
                                class = "tableItem">
                                <input type = "checkbox" value = "{{f.value.IsThematic}}" style = "width: 13px; height: 13px;"
                                    [(ngModel)] = "f.value.IsThematic" />
                                <label for = "chkThematic">Yes</label>
                            </td>
                            <td [attr.id] = "'f.value.Id'" *ngIf = "!EditMode[f.value.Id] && c == 'Is Thematic?'"
                                class = "tableItem">
                                {{ f.value.IsThematic == true ? 'Yes' : 'No'}}
                            </td>

                            <td class = "tableItem" *ngIf = "c == 'Buttons1' && CanEdit">

                                <button *ngIf = "!EditMode[f.value.Id]" type = "button"
                                    class = "btn btn-primary btn mr-1 "
                                    (click) = "buttonClicked(f.value.Id)">Edit</button>
                                <button *ngIf = "EditMode[f.value.Id]" type = "button"
                                    class = "btn btn-primary btn mr-1"
                                    (click) = "Update(f.value.Id)">Save</button>
                                <button *ngIf = "EditMode[f.value.Id]" type = "button"
                                    class = "btn btn-primary btn mr-1"
                                    (click) = "Delete(f.value.Id)">Delete</button>
                                <button *ngIf = "EditMode[f.value.Id]" type = "button"
                                    class = "btn btn-primary btn mr-1"
                                    (click) = "buttonClicked(f.value.Id)">Cancel</button>

                            </td>

                        </ng-container>
                    </ng-container>

                </tr>
            </table>
        </div>
    </div>
</div>

Обновление 1

Попробовав решение darthnach, возникла небольшая проблема при прокрутке. Я вижу содержимое на полях

css

 th {
        padding: 7px;
        position: sticky;
        left:0;
        min-width: 300px;
        background-color:#f5f7f7;

        }

Скриншот 1 Исправить заголовки столбцов при горизонтальной прокрутке

Скриншот 2 Исправить заголовки столбцов при горизонтальной прокрутке

Вот стекблиц

stackblitz.com/edit/angular-d1mzew

Обновление 2

Исправление для решения проблемы с границей при прокрутке, но видимость текста сохраняется при прокрутке

Исправить заголовки столбцов при горизонтальной прокрутке

Вы можете просто удалить оператор CSS в th, установив его позицию. Если что-то есть fixed, оно всегда остается там, где оно есть. Вы можете прочитать больше здесь: developer.mozilla.org/en-US/docs/Web/CSS/position

adr5240 02.07.2019 18:25

И вы против любого решения, сделанного на Javascript?

Mister Jojo 02.07.2019 19:48
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
7
2
1 029
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы можете попробовать этот код для первого столбца.

div {
  overflow-x:scroll;  
  margin-left:6em;
  width: 300px;
    }
table th, td{
  border: 1px solid #000;
}
.first-col {
  position:absolute;
	width:6em;
	left:0;
  text-align: center;
  background-color: #ccc;
    }
<div>
  <table>
    <thead>
      <tr>
        <th class = "first-col">text</th>
        <th>value</th>
        <th>value2
        </th>
        <th>value2
        </th>
        <th>value3
        </th>
        <th>value4
        </th>
        <th>value5
        </th>
        <th>value6
        </th>
        <th>value7
        </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class = "first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class = "first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class = "first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class = "first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class = "first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class = "first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class = "first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td class = "first-col">lorem ipsum</td>
        <td><strong>0</strong>
        </td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
    </tbody>

  </table>

</div>

В своем ответе вы указали фиксированную ширину. Я не могу указать фиксированную ширину моей таблицы, так как она охватывает весь экран и будет зависеть от разных размеров экрана. Также как вписать логику в мой html-код, поскольку я динамически перебираю th и tds

Tom 02.07.2019 15:03

Вам не нужно подгонять логику к HTML-коду, вы только измените код CSS. Это аналогичный пример, и вам не нужно добавлять фиксированную ширину таблицы-контейнера, которая будет принимать ширину в соответствии с данными.

Mak0619 02.07.2019 15:07

Вы применяете класс к первому и тд в html. В вашем коде th и tds определены заранее. Как css будет определять первый th и td в моем случае, когда он динамический

Tom 02.07.2019 18:11

Вы установили ширину: 300px; в элементе div. Это сокращает мой стол

Tom 02.07.2019 18:12

@ Том, ответ Маянка - это то, что ты хочешь, все, что тебе нужно сделать, это изменить .first-col {} на th {}. Просто удалите ширину div, которая есть только в этом примере.

mullac 03.07.2019 08:22

Привет, Каллум, я обновил пост со своей проблемой. Столбец теперь исправлен, но я могу видеть данные через отступы, примененные к границам.

Tom 03.07.2019 09:43

Просто удалите фиксированную позицию из th и добавьте

th {
  position: sticky;
  left:0;
}

Это очень близкое решение, но одна проблема. Во время прокрутки я вижу фоновое содержимое за первым заголовком при прокрутке.

Tom 02.07.2019 19:15

Я исправил эту проблему, установив background-color:#f5f7f7; но есть одна маленькая проблема. Я обновил скриншот в своем посте

Tom 02.07.2019 19:35

Возможно, мне нужно посмотреть код с содержимым, но я думаю, что это можно исправить с помощью поля, содержащего все, с переполнением: скрыто; причина, вероятно, в том, что ng-контейнер показывает дополнительный контент

darthnach 02.07.2019 20:33

Извините, я не понял, где мне поставить overflow:hidden

Tom 02.07.2019 21:24

Можете ли вы сделать блиц или что-то еще для предварительного просмотра вашего кода?

darthnach 02.07.2019 21:44

Отлично, просто измените .card-body{padding:10px} на .card-body{margin: 10px 0;}. Это создавало пространство внутри границ контейнера, и вам нужно было пространство за пределами границ, чтобы отделить его от другого содержимого на вашей странице. stackblitz.com/edit/…

darthnach 03.07.2019 18:55

В .card-body вместо отступа попробуйте маржу, это может решить вашу проблему, я носил на stackblitz -- https://stackblitz.com/edit/angular-d1mzew

.card-body {
    flex: 1 1 auto;
    /* padding: 10px; */
    margin: 10px;
}

Stackblitz, которым вы поделились, не отражает исправление

Tom 03.07.2019 11:34

Я пробовал использовать css в своем решении, и это намного лучше, чем раньше, но при прокрутке я вижу, как исчезает граница таблицы.

Tom 03.07.2019 11:42

я не могу сохранить bliz и отправить, вы можете попробовать, применив свойство в style.css .card-body { flex: 1 1 auto; margin: 10px; }

Sethuraman 03.07.2019 11:42

Как я упоминал ранее, я пытался, и это намного лучше, чем раньше, но граница таблицы исчезает при прокрутке

Tom 03.07.2019 11:44

Вы можете попробовать еще одно решение, измените свойство «left:-10px» на «position: sticky» th { padding: 7px; position: sticky; left:-10px; min-width: 300px; background-color:#f5f7f7; }

Sethuraman 03.07.2019 11:45

left - 10px перемещает заголовок немного влево при прокрутке

Tom 03.07.2019 11:48

@Tom Не могли бы вы объяснить, как граница исчезает при прокрутке? Во время тестирования на Mac я мог видеть, что после замены padding на margin поведение такое же.

Furqan Rahamath 06.07.2019 13:40
Ответ принят как подходящий

Основываясь на ответе @Сетураман, если вы замените padding на margin, а затем поместите границу в таблицу упаковки div, это может решить вашу проблему границы (не уверен, что это то, что вы пытаетесь решить)

Вы можете попробовать изменить ниже:

.card-body {
    flex: 1 1 auto;
    padding: 0;
    margin: 10px 0;
    /* border: 1px solid lightgray; */ <-- You can add or remove this based on your need
}

Это до и после изменения вышеуказанного класса.

Кроме того, вы можете удалить интервал между границами, чтобы избежать разрыва прокрутки в 2 пикселя на элементах th при прокрутке содержимого влево.

.fundClassesTable[_ngcontent-xcq-c0] {
    table-layout: fixed;
    border-spacing: 0;
}

Пожалуйста, дайте мне знать, если это поможет или вы ищете что-то еще.

поле 10px 0; действительно добавил границу, но я все еще вижу текст на левом поле при прокрутке. Обновил пост

Tom 07.07.2019 08:57

Это может быть потому, что вы еще не установили отступ 0. Я обновил свой ответ, добавив заполнение CSS в класс .card-body. Пожалуйста, попробуйте.

Furqan Rahamath 07.07.2019 21:12

@Tom Пожалуйста, проверьте скриншоты в моем ответе таблицы до и после удаления заполнения.

Furqan Rahamath 07.07.2019 21:18

Вы загрузили скриншот

Tom 07.07.2019 21:24

Да. Пожалуйста, взгляните.

Furqan Rahamath 07.07.2019 21:47

@ Том, ты еще никому не присудил награду. Вы можете разделить награду и отдать ее людям, которые вам помогли.

Furqan Rahamath 09.07.2019 07:33

Я принял ваш ответ, поэтому награда не присуждается вам

Tom 09.07.2019 14:54

Нет, он не присудил награду. Я думаю, вам нужно сделать это самостоятельно. Поскольку этот вопрос находится в льготном периоде, вам необходимо вручную присудить вознаграждение.

Furqan Rahamath 09.07.2019 14:59

@ Том Тебе не кажется, что было бы лучше разделить награду? :) Я не уверен, что этот вариант существует. Но просто интересно.

Furqan Rahamath 09.07.2019 18:53

Это не дает мне возможности расстаться. Момент, который я вам назначил, говорит, что нельзя повторить

Tom 09.07.2019 19:00

На самом деле, награда не была назначена мне. Так что мне просто интересно, потому что одной из причин, по которой я потратил на это время, была награда. В любом случае, если вы не можете отменить это, не проблема. Все в порядке.

Furqan Rahamath 09.07.2019 19:12

Попробуйте это, установив position:sticky и left:-10px. Вот стекблиз для того же. Это удовлетворит ваше требование, я думаю

th{
    position: sticky;
    left: -10px;

}

Другие вопросы по теме