Подтвердить что ты не робот

Как сделать переполненный элемент flexbox иметь ширину своих детей?

Я пытаюсь перекрыть табличную сетку с помощью прокрутки с помощью Flexbox. no horizontal scroll

Большинство из них работает нормально, но есть ли способ заставить строки иметь ширину их содержимого при горизонтальной прокрутке?

горизонтальная прокрутка по

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

http://jsbin.com/fedisozafe/embed?html,css,output

$('.tbody').on('scroll', function(e) {
    $(this).siblings().scrollLeft($(this).scrollLeft());
});

$('.tbody').perfectScrollbar();

$(window).on('resize', function(e) {
    $('.tbody')
      .perfectScrollbar('update')
      .siblings()
        .scrollLeft($(this).scrollLeft());
});


angular.module('app', [])
    .controller('testController', [
        '$scope',
        function($scope) {
            this.n = 5;
            $scope.$watch(() => this.n, () => this.collection = _.range(this.n));
        }
    ]);
* {
    box-sizing: border-box;
    border-collapse: collapse;
}
.table {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    border: solid 1px red;
}
.table > * {
    border-top: solid 1px transparent;
    border-bottom: solid 1px transparent;
}
.thead {
    border-bottom: solid 1px red;
}
.tfoot {
    border-top: solid 1px red;
}
.thead {
    flex: none;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    order: -1;
    background-color: lightgoldenrodyellow;
}
.tbody {
    position: relative;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    justify-content: space-between;
    background-color: lightgray;
}
.tfoot {
    flex: none;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    order: 1;
    background-color: lightblue;
}
.tr {
    display: flex;
    flex: 1 0 20px;
    justify-content: space-between;
    align-items: center;
}
.tr:nth-child(2n) {
    background-color: white;
}
.td,
.th {
    flex: 1 0 60px;
    display: inline-flex;
}
.th {
    font-weight: bold;
}
<!doctype html>
<html ng-app="app">
    <head>
        <meta charset="utf-8">
        <title></title>
        <meta name="viewport" content="width=device-width">

		<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
		<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
		<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.5.1/lodash.min.js"></script>
		<script src="//cdnjs.cloudflare.com/ajax/libs/jquery.perfect-scrollbar/0.6.10/js/min/perfect-scrollbar.jquery.min.js"></script>

		<link rel="stylesheet" href="#" onclick="location.href='https://cdnjs.cloudflare.com/ajax/libs/jquery.perfect-scrollbar/0.6.10/css/perfect-scrollbar.min.css'; return false;"/>
	</head>
	<body ng-controller="testController as ctrl">
	<input type="number" ng-model="ctrl.n" ng-max="100" />
	<div style="display: flex">
		<div style="flex: 1 1 auto">
			<table class="table" style="width: 40vw; height: 40vh">
				<tbody class="tbody" style="height: calc(100% - 60px)">
					<tr class="tr" ng-repeat="item in ctrl.collection" style="min-width: 200px">
						<th class="th">{{item}}</th>
						<th class="td" style="flex-basis: 200px">{{item}}</th>
						<th class="td">{{item}}</th>
						<th class="td">{{item}}</th>
						<th class="td">{{item}}</th>
					</tr>
				</tbody>
				<thead class="thead">
					<tr class="tr">
						<td class="th">A</td>
						<td class="th" style="flex-basis: 200px">B</td>
						<td class="th">C</td>
						<td class="th">D</td>
						<td class="th">E</td>
					</tr>
				</thead>
				<tfoot class="tfoot">
					<tr class="tr">
						<th class="th">A</th>
						<th class="th" style="flex-basis: 200px">B</th>
						<th class="th">C</th>
						<th class="th">D</th>
						<th class="th">E</th>
					</tr>
				</tfoot>
			</table>
		</div>
		<div style="flex: 1 1 auto">
			<div class="table" style="width: 40vw; height: 40vh">
				<div class="tbody" style="height: calc(100% - 60px)">
				<div class="tr" ng-repeat="item in ctrl.collection">
					<div class="th">{{item}}</div>
					<div class="td" style="flex-basis: 200px">{{item}}</div>
					<div class="td">{{item}}</div>
					<div class="td">{{item}}</div>
					<div class="td">{{item}}</div>
				</div>
				</div>
				<div class="thead">
				<div class="tr">
					<div class="th">A</div>
					<div class="th" style="flex-basis: 200px">B</div>
					<div class="th">C</div>
					<div class="th">D</div>
					<div class="th">E</div>
				</div>
				</div>
				<div class="tfoot">
				<div class="tr">
					<div class="th">A</div>
					<div class="th" style="flex-basis: 200px">B</div>
					<div class="th">C</div>
					<div class="th">D</div>
					<div class="th">E</div>
				</div>
				</div>
			</div>
		</div>
	</div>

	</body>
</html>
4b9b3361

Ответ 1

Ошибок не было, HTML, CSS и JS (я предполагаю, что Angular и loDash хороши, чтобы идти.) все хорошо. Таким образом, OP просто нужен способ сжимать строки. Строки расширены в странном переполнении? Были некоторые изменения в CSS, но они были больше для эстетики и небольших настроек. Основные изменения стиля следующие:

    .tr {
      display: flex;
      min-width: -moz-fit-content;
      min-width: -webkit-fit-content;
      min-width: fit-content;
      flex: 1 0 20px;
      justify-content: flex-end;
    } 

fit-content - это старое, но малоизвестное свойство, все еще находящееся на нем экспериментальной стадии. То, что он в основном делает, это заставить элемент обернуть его контентом в идеальной форме. Поэтому, если вы примените его к родительскому элементу, родитель будет таким же широким, как и контент, и он будет увеличиваться и уменьшаться с содержимым.

- Result: The overflow was gone but `tr` did not extend.

Удален flex-direction: column, поэтому он будет по умолчанию flex-direction: row Я понял, что tr, текущее в вертикальном направлении, вероятно, остановится коротко и резко.

- Result: The `tr` extended, but the `td`s and `th`s were not aligned.

justify-content: flex-end применяется для сдвига столбцов вправо, вызвав проблему в правой части таблицы.

- Result: http://jsbin.com/godoqi/3/edit?css,output

table-layout: fixed также был применен к таблице, чтобы больше контролировать ширину столбцов.

- Result: See previous result.

jsBin

Отрывок

$('.tbody').on('scroll', function(e) {
  $(this).siblings().scrollLeft($(this).scrollLeft());
});

$('.tbody').perfectScrollbar();

$(window).on('resize', function(e) {
  $('.tbody')
    .perfectScrollbar('update')
    .siblings()
    .scrollLeft($(this).scrollLeft());
});


angular.module('app', [])
  .controller('testController', [
    '$scope',
    function($scope) {
      this.n = 5;
      $scope.$watch(() => this.n, () => this.collection = _.range(this.n));
    }
  ]);
* {
  box-sizing: border-box;
}
.table {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  border: solid 1px red;
  border-collapse: collapse;
  table-layout: fixed;
}
.table > * {
  border-top: solid 1px transparent;
  border-bottom: solid 1px transparent;
}
.thead {
  border-bottom: solid 1px red;
}
.tfoot {
  border-top: solid 1px red;
}
.thead {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  order: -1;
  background-color: lightgoldenrodyellow;
}
.tbody {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-content: space-between;
  background-color: lightgray;
}
.tfoot {
  flex: none;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  order: 1;
  background-color: lightblue;
  text-align: center;
}
.tr {
  display: flex;
  min-width: -moz-fit-content;
  min-width: -webkit-fit-content;
  min-width: fit-content;
  flex: 1 0 20px;
  justify-content: flex-end;
}
.tr:nth-child(2n) {
  background-color: white;
}
.td,
.th {
  flex: 0 1 60px;
  text-align: center;
}
.th {
  font-weight: bold;
}
.ng-not-empty {
  text-align: center;
  width: 8ex;
}
<!doctype html>
<html ng-app="app">

<head>
  <meta charset="utf-8">
  <title></title>
  <meta name="viewport" content="width=device-width">

  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.5.1/lodash.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery.perfect-scrollbar/0.6.10/js/min/perfect-scrollbar.jquery.min.js"></script>

  <link rel="stylesheet" href="#" onclick="location.href='https://cdnjs.cloudflare.com/ajax/libs/jquery.perfect-scrollbar/0.6.10/css/perfect-scrollbar.min.css'; return false;" />
</head>

<body ng-controller="testController as ctrl">
  <input type="number" ng-model="ctrl.n" ng-max="100" />
  <div style="display: flex">
    <div style="flex: 1 1 auto">
      <table class="table" style="width: 40vw; height: 40vh">
        <tbody class="tbody" style="height: calc(100% - 60px)">
          <tr class="tr" ng-repeat="item in ctrl.collection" style="min-width: 200px">
            <th class="th">{{item}}</th>
            <th class="td" style="flex-basis: 200px">{{item}}</th>
            <th class="td">{{item}}</th>
            <th class="td">{{item}}</th>
            <th class="td">{{item}}</th>
          </tr>
        </tbody>
        <thead class="thead">
          <tr class="tr">
            <td class="th">A</td>
            <td class="th" style="flex-basis: 200px">B</td>
            <td class="th">C</td>
            <td class="th">D</td>
            <td class="th">E</td>
          </tr>
        </thead>
        <tfoot class="tfoot">
          <tr class="tr">
            <th class="th">A</th>
            <th class="th" style="flex-basis: 200px">B</th>
            <th class="th">C</th>
            <th class="th">D</th>
            <th class="th">E</th>
          </tr>
        </tfoot>
      </table>
    </div>
    <div style="flex: 1 1 auto">
      <div class="table" style="width: 40vw; height: 40vh">
        <div class="tbody" style="height: calc(100% - 60px)">
          <div class="tr" ng-repeat="item in ctrl.collection">
            <div class="th">{{item}}</div>
            <div class="td" style="flex-basis: 200px">{{item}}</div>
            <div class="td">{{item}}</div>
            <div class="td">{{item}}</div>
            <div class="td">{{item}}</div>
          </div>
        </div>
        <div class="thead">
          <div class="tr">
            <div class="th">A</div>
            <div class="th" style="flex-basis: 200px">B</div>
            <div class="th">C</div>
            <div class="th">D</div>
            <div class="th">E</div>
          </div>
        </div>
        <div class="tfoot">
          <div class="tr">
            <div class="th">A</div>
            <div class="th" style="flex-basis: 200px">B</div>
            <div class="th">C</div>
            <div class="th">D</div>
            <div class="th">E</div>
          </div>
        </div>
      </div>
    </div>
  </div>

</body>

</html>