TLDR; I can set the max-width of an element to min-content, but I how can I set it to min-content * n?
I have an element with dynamically determined content inside a container. The page is viewed on a wide viewport (viewport width > table's min-width). Something like this:
<section class="container">
<div class="data"><!-- Some content here --></div>
</section>
.container {
display: grid;
justify-items: center;
justify-content: stretch;
}
.data {
min-width: min-content;
}
I would like the div to stretch in width, but only to an extent. Again, the content of the div is dynamically determined, so I cannot set a fixed value for max-width. Therefore I would like to set its max-width to be a multiple of its min-width, something like this:
.data {
min-width: min-content;
max-width: calc(min-content * 1.5);
}
Obviously I cannot do this because min-content is a named property value, not a resolvable number. So how should I achieve this in CSS only? Or am I obliged to use JS? Thanks in advance.
Related
I would like to have a grid layout on a page where the grid stretches out to the entire viewport, and the rows have a minimum height. The simplest example would be a grid with a single cell (see code snippet below).
The problem I am having is that when the height of the viewport is less than the defined minimum row-height, the row vertically overflows its container. With the added red and green borders in the below example it's visible that the row's height isn't going below the defined 500 pixels, but the grid-container is still sized to the viewport which is now shorter than 500 pixels.
If I remove the height CSS attribute from the grid class, the container doesn't shrink below its content, but it also doesn't fill out the vertical space when the viewport is taller than 500 pixels. Since I want the grid to fill the entire page, I need the height CSS attribute. I've also added the min-height: fit-content attribute which is supposed to prevent the used value of the height property from becoming smaller than the value specified for min-height but it doesn't work (not with the defined fit-content value - it works as expected with an exact value, for example 300px).
In a similar question the culprit was the percentage values used for the gaps, but in this case there is nothing relatively sized. Even if replace the grid-template-rows: minmax(500px, 1fr); property with the fixed grid-template-rows: 500px;, it still behaves the same way.
body {
margin: 0;
}
.grid {
display: grid;
grid-template-rows: minmax(500px, 1fr);
height: 100vh;
min-height: fit-content;
width: 100vw;
}
.bordered {
border: 10px solid green;
}
<div class="grid bordered" style="border-color: red;">
<div class="bordered">Some content</div>
</div>
What I would like to have is a grid that fills out the entire viewport and where the grid-container is never smaller than its content. What am I missing?
Something to know is that as soon as a min height of a row, or the combined height of multiple rows, is greater than the height of the viewport, you will have a scroll. Beyond that, the snippet below, I hope does what you are looking for. I added comments in the code.
/* lines I added */
*{
box-sizing: border-box;
}
body {
margin: 0;
}
.grid {
display: grid;
/* 100 is for the small viewport here in the code snippet */
grid-template-rows: repeat(auto-fit, minmax(100px, 1fr));
min-height : 100vh;
}
.bordered {
border: 10px solid green;
}
<div class="grid bordered" style="border-color: red;">
<div class="bordered">Some content</div>
</div>
I have a layout that looks like this:
<div class="container">
<div class="input"></div>
<div class="filter buttons"></div>
<div class="content"></div>
</div>
And this is their styling:
.container {
display: grid;
grid-row-gap: 30px;
padding: 30px 15px;
}
.input {
max-width: 350px;
}
.filter-buttons {
display: grid;
grid-template-columns: repeat( auto-fit, 170px);
grid-gap: 10px;
}
You can see the codesanbox here. What I would like is to have the container width set by the width of the row with filter buttons. I can't have it fixed, since filter buttons have auto wrapping set with auto-fit. And since content takes the full width, the containers width is set by the content width.
What I am trying to achieve is to have a responsive layout with css grid and without having to use media queries, where container would follow the width of filter_buttons div.
So, it would look like this on the small screens:
And like this on bigger screens:
How can I achieve that kind of layout?
I have a div.grid that contains multiple div.column inside using flexbox. When a div.column increases in height due to having more content inside, all other div.column also increase in height.
It is to my understaind that this shouldn't help as their height is set to auto.
Also, my grid is using the flex display, with flex-wrap: wrap. I think is what is causing it, but I haven't found any explanation to why it is changing the children's height.
I have tried changing the following properties, in different combinations and manners, of parent and children: position, display, height.
These are the computed styles only, not my actual code.
div.grid {
display: flex;
flex-wrap: wrap;
width: 960px;
}
div.column {
display: block;
flex-basis: 37.5%;
flex-grow: 0;
flex-shrink: 0;
/* height is actually set to auto, but it is computed like this */
height: 132px;
}
<div class="grid">
<div class="column">something</div>
<div class="column">something<br>else<br>here</div>
<div class="column">something</div>
</div>
I expected the children to not fill the full height of the parent when the children don't all have the same amount of content.
As LGSon has asnwered in the comments:
Using flex: display automatically defaults align-items to stretch making the height of the children stretch to fill the height of the wrapper. It is also not shown in the computed properties, which is why it didn't cross my mind to check it.
Therefore, the solution was to add align-items: flex-start to .grid.
I'm new to grids and I'm trying to understand some cell sizing concepts.
I have a container that is set to display: grid and a main element centered in the grid where the min-content column/row is.
.main-container {
display: grid;
grid-template-columns: 1fr min-content 1fr;
grid-template-rows: 1fr min-content 1fr;
}
.main-container main {
grid-column: span 1
grid-column-start: 2
grid-row: span 1
grid-row-start: 2
}
canvas {
width: 800px;
height: 600px;
}
and html
<!-- page -->
<html>
...
<body>
<div class="main-container">
<main>
<canvas />
</main>
</div>
</body>
</html>
codepen example
The application will center around the happenings of the canvas, and due to the nature of aspect ratios in canvas rendering, I want the center grid cell to conform to the size of the canvas and not the other way around.
I expect that due to both main and canvas being border-box'ed and the size of the canvas being absolute, then the main element should theoretically not effect the calculated min-content height. this isn't the case for width but somehow the height adds 4 extra pixels.
Where did these extra height pixels come from and how can I ensure they don't appear
Setting the height of main explicitly to 600px does solve the problem, however this is redundant information and I anticipate there is a solution not involving hardcoded height bandaids.
Please give float:left to canvas or add height to main{height:300px} and give height to canvas {height:100%}
I've made a grid template with rows of 1fr 1fr 1fr. In the middle row, there are a list of inline images.
In Chrome and Firefox, the images respect the height of the grid row and adapt properly. However, in Safari 10.1.2 and Safari TP 31, there appears to be a combination of the images overflowing the row and not scaling the image widths appropriately.
Perhaps I'm doing something wrong? Or is this a Safari bug? And if so, is there a workaround?
Safari 10.1
Safari TP
Chrome 60
#grid {
height: 100vh;
display: grid;
grid-template-rows: 1fr 1fr 1fr;
}
#thumbnailContainer {
position: inherit;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
}
img {
display: inline;
height: 100%;
width: auto;
}
header,
footer {
background-color: dodgerblue;
}
<div id="grid">
<header>Header</header>
<div id="thumbnailContainer">
<img src="https://c2.staticflickr.com/8/7591/16903911106_b7ced9d758.jpg">
<img src="https://c1.staticflickr.com/9/8740/16927517701_810fcb2a7c.jpg">
<img src="https://c2.staticflickr.com/8/7637/16902583636_15138a68f0.jpg">
<img src="https://c2.staticflickr.com/8/7614/16927530091_6755845b13.jpg">
<img src="https://c1.staticflickr.com/9/8700/16741099010_d0ecd9df1f.jpg">
<img src="https://c1.staticflickr.com/9/8745/16927567841_74fd20d01d.jpg">
</div>
<footer>Footer</footer>
</div>
https://jsfiddle.net/fqkjhh6m/1/
Short Answer
The problem is that Safari is not recognizing the height: 100% on the img elements.
Explanation
This is not a Safari bug. It's just a different interpretation of the spec.
When dealing with percentage heights, some browsers (like Safari) adhere to the traditional interpretation of the spec, which requires a defined height on the parent.
10.5 Content height: the height
property
<percentage>
Specifies a percentage height. The percentage is calculated with
respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the used height is calculated as if auto was specified.
In other words, a percentage height on an in-flow element will be recognized only when the parent has a defined height.
Some browsers, such as Chrome and Firefox, have moved past this interpretation and now accept flex and grid heights as an adequate parent reference for a child with a percentage height.
But Safari is stuck in the past. This doesn't mean it's wrong, invalid or a bug.
The last substantive update to the CSS height definition was in 1998 (CSS2). With so many new CSS properties and technologies since that time, the definition has become obsolete, unclear and woefully incomplete. Until the definition is updated for modern use, browser rendering variations can be expected.
Solution
Since Safari doesn't recognize the height: 100% on the img elements, and you can't specify a height on the parent (#thumbnailContainer) because that height is defined by grid-template-rows: 1fr on the top-level container, you can try using flexbox.
By making #thumbnailContainer a flex container, you can define the size of the images (flex items) using flex properties.
#grid {
height: 100vh;
display: grid;
grid-template-rows: 1fr 1fr 1fr;
}
#thumbnailContainer {
display: flex;
overflow-x: auto;
overflow-y: hidden;
min-width: 0;
min-height: 0;
}
img {
flex: 0 0 35%;
min-width: 0;
object-fit: cover;
}
header, footer {
background-color: dodgerblue;
}
<div id="grid">
<header>Header</header>
<div id="thumbnailContainer">
<img src="https://c2.staticflickr.com/8/7591/16903911106_b7ced9d758.jpg">
<img src="https://c1.staticflickr.com/9/8740/16927517701_810fcb2a7c.jpg">
<img src="https://c2.staticflickr.com/8/7637/16902583636_15138a68f0.jpg">
<img src="https://c2.staticflickr.com/8/7614/16927530091_6755845b13.jpg">
<img src="https://c1.staticflickr.com/9/8700/16741099010_d0ecd9df1f.jpg">
<img src="https://c1.staticflickr.com/9/8745/16927567841_74fd20d01d.jpg">
</div>
<footer>Footer</footer>
</div>
jsFiddle
More information
Working with the CSS height property and percentage values
Chrome / Safari not filling 100% height of flex parent
Why doesn't flex item shrink past content size?
Why isn't object-fit working in flexbox?
Don't ask me why, but wrapping the grid parent with a simple div solved my problem.
This article (https://newbedev.com/why-is-css-grid-row-height-different-in-safari) mentions:
Put display:grid on the div surrounding your grid container.
My problem was solved just by wrapping the grid container with a div. Just wanted to mention another solution. I hope someone can add an explanation for what is happening here.