网格单元格上 100% 宽度的水平滚动
horizontal scroll with 100% width on grid cell
我想要一个 css 网格,在网格的每个单元格内,我想要一个最大尺寸为单元格宽度 100% 的标题。如果标题太长,我想滚动。
这是目前滚动行为正确但长标题宽度固定的情况。我想要的不是固定宽度,而是单元格宽度的 100%(因此灰色块应该与红色框一样长)
codePen: https://codepen.io/vincent2303/pen/ExwZEpW
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 800px;
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
.title-wrapper {
background-color: #bdc3c7;
width: 300px;
overflow-x: scroll;
}
<div class=grid>
<div>
<div class="title-wrapper">
<h2>long title, i can scroll---------</h2>
</div>
<div class="box"></div>
</div>
<div>
<h2>Short title</h2>
<div class="box"></div>
</div>
</div>
有人有想法吗?
注意:为了简化代码示例,.grid
class 的宽度为 800px
但实际上,它的宽度由其 parent 定义我无法预测宽度(我正在开发一个 React 应用程序,这段代码将实现一个在多个不同大小的地方使用的组件)。
正如这里评论的那样,有可能:
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 800px;
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 50vh;
max-width: 400px;
}
.title-wrapper {
background-color: #bdc3c7;
width: 100%;
overflow-x: scroll;
}
<div class=grid >
<div>
<div class="box" >
<div class="title-wrapper" >
<h2>long title, i can scroll---------------------------------</h2>
</div>
</div>
</div>
<div>
<div class="box" >
<h2>Short title</h2>
</div>
</div>
</div>
没有 JavaScript 似乎很难,Dev 他的答案有效,但它涉及固定的最大宽度。
我有一个 JavaScript 的解决方案似乎有效。
/* Execute when the DOM is loaded, because otherwise the HTML elements might nog be in the DOM. */
window.addEventListener( 'DOMContentLoaded', () => {
generateGridItemsWidthVariable()
} )
/* Execute when the window is resized, because the width of the boxes might change. */
window.addEventListener( 'resize', () => {
generateGridItemsWidthVariable()
} )
/* Generate the variable for the grid items. */
function generateGridItemsWidthVariable() {
/* Select all the grid items and create an array to loop trough. */
let gridItems = Array.from( document.getElementsByClassName( 'grid__item' ) )
/* Loop trough the grid items. */
gridItems.forEach( gridItem => {
/* Reset the grid item width, because otherwise the item won't resize. */
gridItem.style.setProperty( '--grid-item--width', '' )
/* Get the width of the grid item. */
let gridItemWidth = gridItem.clientWidth.toString()
/* Set the width of the grid item as a CSS variable. */
gridItem.style.setProperty( '--grid-item--width', gridItemWidth + 'px' )
} )
}
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 100%;
max-width: 800px;
gap: 20px;
}
.grid__item {
--grid-item--width: 10px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
.title-wrapper {
background-color: #bdc3c7;
width: 100%;
}
.title-wrapper h2 {
max-width: var(--grid-item--width);
overflow-x: scroll;
}
<div class=grid >
<div class="grid__item">
<div class="title-wrapper" >
<h2>long title, i can scroll-----------------------</h2>
</div>
<div class="box" ></div>
</div>
<div class="grid__item">
<h2>Short title</h2>
<div class="box" ></div>
</div>
</div>
如果您的网格可能包含溢出的内容,您将无法使用 1fr
,原因如下:
1fr
只是 minmax(auto, 1fr)
. 的缩写
minmax(a, b)
变为 a
(没有任何 minmax)当 a >= b
是 true
.
- 因此在您的情况下,您的网格的行为就好像您将其定义为
grid-template-columns: auto 1fr;
,因为第一列的 auto
大于 1fr
。
要解决这个问题,您需要告诉您的网格,当内容变得太宽时不允许扩展单元格。
使用minmax(0, 1fr)
代替1fr
:
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
width: 800px;
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
h2 {
background-color: #bdc3c7;
overflow-x: scroll;
}
<div class=grid>
<div>
<h2>long title, i can scroll------------------ - - - - ----</h2>
<div class="box"></div>
</div>
<div>
<h2>Short title</h2>
<div class="box"></div>
</div>
</div>
那么 1fr
解析为 minmax(auto, 1fr)
,这意味着网格列的最小宽度为 min-content
,即大于 1fr
。有一个快速解决这个问题的方法,只需将 1fr
替换为 minmax(0px, 1fr)
,这样,父级的宽度就分为两列,这样你就可以得到你想要的滚动条。
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
h2 {
background-color: #bdc3c7;
overflow-x: auto;
}
<div class=grid>
<div>
<h2>long title, i can scroll----------------------------</h2>
<div class="box"></div>
</div>
<div>
<h2>Short title</h2>
<div class="box"></div>
</div>
</div>
我想要一个 css 网格,在网格的每个单元格内,我想要一个最大尺寸为单元格宽度 100% 的标题。如果标题太长,我想滚动。
这是目前滚动行为正确但长标题宽度固定的情况。我想要的不是固定宽度,而是单元格宽度的 100%(因此灰色块应该与红色框一样长)
codePen: https://codepen.io/vincent2303/pen/ExwZEpW
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 800px;
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
.title-wrapper {
background-color: #bdc3c7;
width: 300px;
overflow-x: scroll;
}
<div class=grid>
<div>
<div class="title-wrapper">
<h2>long title, i can scroll---------</h2>
</div>
<div class="box"></div>
</div>
<div>
<h2>Short title</h2>
<div class="box"></div>
</div>
</div>
有人有想法吗?
注意:为了简化代码示例,.grid
class 的宽度为 800px
但实际上,它的宽度由其 parent 定义我无法预测宽度(我正在开发一个 React 应用程序,这段代码将实现一个在多个不同大小的地方使用的组件)。
正如这里评论的那样,有可能:
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 800px;
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 50vh;
max-width: 400px;
}
.title-wrapper {
background-color: #bdc3c7;
width: 100%;
overflow-x: scroll;
}
<div class=grid >
<div>
<div class="box" >
<div class="title-wrapper" >
<h2>long title, i can scroll---------------------------------</h2>
</div>
</div>
</div>
<div>
<div class="box" >
<h2>Short title</h2>
</div>
</div>
</div>
没有 JavaScript 似乎很难,Dev 他的答案有效,但它涉及固定的最大宽度。
我有一个 JavaScript 的解决方案似乎有效。
/* Execute when the DOM is loaded, because otherwise the HTML elements might nog be in the DOM. */
window.addEventListener( 'DOMContentLoaded', () => {
generateGridItemsWidthVariable()
} )
/* Execute when the window is resized, because the width of the boxes might change. */
window.addEventListener( 'resize', () => {
generateGridItemsWidthVariable()
} )
/* Generate the variable for the grid items. */
function generateGridItemsWidthVariable() {
/* Select all the grid items and create an array to loop trough. */
let gridItems = Array.from( document.getElementsByClassName( 'grid__item' ) )
/* Loop trough the grid items. */
gridItems.forEach( gridItem => {
/* Reset the grid item width, because otherwise the item won't resize. */
gridItem.style.setProperty( '--grid-item--width', '' )
/* Get the width of the grid item. */
let gridItemWidth = gridItem.clientWidth.toString()
/* Set the width of the grid item as a CSS variable. */
gridItem.style.setProperty( '--grid-item--width', gridItemWidth + 'px' )
} )
}
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 100%;
max-width: 800px;
gap: 20px;
}
.grid__item {
--grid-item--width: 10px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
.title-wrapper {
background-color: #bdc3c7;
width: 100%;
}
.title-wrapper h2 {
max-width: var(--grid-item--width);
overflow-x: scroll;
}
<div class=grid >
<div class="grid__item">
<div class="title-wrapper" >
<h2>long title, i can scroll-----------------------</h2>
</div>
<div class="box" ></div>
</div>
<div class="grid__item">
<h2>Short title</h2>
<div class="box" ></div>
</div>
</div>
如果您的网格可能包含溢出的内容,您将无法使用 1fr
,原因如下:
1fr
只是minmax(auto, 1fr)
. 的缩写
minmax(a, b)
变为a
(没有任何 minmax)当a >= b
是true
.- 因此在您的情况下,您的网格的行为就好像您将其定义为
grid-template-columns: auto 1fr;
,因为第一列的auto
大于1fr
。
要解决这个问题,您需要告诉您的网格,当内容变得太宽时不允许扩展单元格。
使用minmax(0, 1fr)
代替1fr
:
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
width: 800px;
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
h2 {
background-color: #bdc3c7;
overflow-x: scroll;
}
<div class=grid>
<div>
<h2>long title, i can scroll------------------ - - - - ----</h2>
<div class="box"></div>
</div>
<div>
<h2>Short title</h2>
<div class="box"></div>
</div>
</div>
那么 1fr
解析为 minmax(auto, 1fr)
,这意味着网格列的最小宽度为 min-content
,即大于 1fr
。有一个快速解决这个问题的方法,只需将 1fr
替换为 minmax(0px, 1fr)
,这样,父级的宽度就分为两列,这样你就可以得到你想要的滚动条。
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
h2 {
background-color: #bdc3c7;
overflow-x: auto;
}
<div class=grid>
<div>
<h2>long title, i can scroll----------------------------</h2>
<div class="box"></div>
</div>
<div>
<h2>Short title</h2>
<div class="box"></div>
</div>
</div>