CSS Grid template with image breaks Firefox - html

I have two lines of text on top of another, each using different font-sizes.
To the left of these text lines, I would like to display an image, automatically scaled in width and height to fit the height of both of these text lines combined, while keeping the original aspect ratio.
I am using css grid trying to achieve this. It does work in chrome, but in firefox, it breaks.
Chrome:
Firefox:
As you can see, firefox fails to properly adjust the image grid area to fit the images size.
How could this be fixed?
The relevant code can be found here:
Jsfiddle: https://jsfiddle.net/5z6grjp2/
.parent {
width: 200px;
display: grid;
border: 1px solid #000;
grid-template-columns: auto 1fr;
grid-template-areas: "image textA" "image textB";
}
.image {
grid-area: image;
height: 100%;
}
.textA {
font-size: 20px;
background-color: #f99;
grid-area: textA;
}
.textB {
font-size: 15px;
background-color: #9f9;
grid-area: textB;
}
<div class="parent">
<img class="image" src="/archer.png">
<div class="textA">Text A</div>
<div class="textB">Text B</div>
</div>

This looks like a bug in Firefox.
The layout renders with the image at its inherent size. The sibling items, sizing to 1fr, don't use the actual remaining space. They use the space available when the image was rendered at its original size. So there's an overlap when the image expands. That's what appears to be happening.
The workaround is to force the image area to expand. A fixed width does this, although I know it may not be what you want.
.parent {
width: 200px;
display: grid;
border: 1px solid #000;
grid-template-columns: auto 1fr;
grid-template-areas: "image textA" "image textB";
}
.image {
grid-area: image;
width: 40px;
height: auto;
}
.textA {
grid-area: textA;
font-size: 20px;
background-color: #f99;
}
.textB {
grid-area: textB;
font-size: 15px;
background-color: #9f9;
}
<div class="parent">
<img class="image" src="http://hordes.io/data/archer.png">
<div class="textA">Text A</div>
<div class="textB">Text B</div>
</div>
jsFiddle demo

Related

How can I shrink the height of a flex child to 50% only?

I am trying to have a UI like this :
This is how I have tried doing it :
A div at the top as cover Image
The next div containing two child divs as profile photo & UI details as -
<div>Image Cover photos<div>
<div style="display : flex;">
<div>profile photo</div>
<div>UI Details Card</div>
</div>
Then I'm using the transform : translateY(-50%) to the profile photo div to move 50 percent of the portion on top of the background cover photo.
This, however creates a problem, the UI details remains at the same place(which is ideal), but the baseline has been changed.I want it to have only 50% of the height, so the baseline matches with the profile photo as well, and also UI details wcard will have some text, I do not want it to overlap on the Cover Image background as well(as that of profile photo). How can I achieve this?
One way to solve this problem is to use CSS grid to place everything.
body {
padding: 100px;
}
.card {
height: 300px;
width: 300px;
display: grid;
grid-template-columns: 1fr 2fr;
grid-template-rows: repeat(3, 1fr);
outline: 1px solid;
}
.details {
background-color: blanchedalmond;
grid-area: 3/2/4/3;
}
.photo {
background-color: aquamarine;
grid-area: 2/1/4/2;
}
.cover {
grid-area: 1/1/3/3;
background-color: grey;
}
.cover img,
.photo img {
height: 100%;
width: 100%;
}
<div class="card">
<div class="cover">
<img src="https://source.unsplash.com/random/?1" alt="">
</div>
<div class="photo">
<img src="https://source.unsplash.com/random/" alt="">
</div>
<div class="details">Details here</div>
</div>
Here's a diagram showing the different grid areas :
Notice the overlap region between the blue box (photo) and the red box (cover). Since the photo div appears after the cover div in the DOM, the photo div will have higher priority and will occupy this overlap region.
You can make a 2 column, 3 row grid and place items where you want them.
Here's a simple example:
.container {
display: grid;
grid-template-columns: 1fr 4fr;
grid-template-rows: 1fr 1fr 1fr;
width: 30vw;
height: 20vw;
}
.container :nth-child(1) {
grid-column: 1 / span 2;
grid-row: 1 / span 2;
background: red;
}
.container :nth-child(2) {
grid-column: 1;
grid-row: 2 / span 2;
background: green;
}
.container :nth-child(3) {
background: blue;
}
<div class="container">
<div></div>
<div></div>
<div></div>
</div>
Obviously you will want to alter the relative sizes of the grid to suit your particular case.
Note: it depends on whether you want to put some text in the first item so that it comes directly above the second item or not as to whether you start the first div in the first column or the second column.

Why are my inline divs at different heights?

I am using a grid container on an html page; inside two adjacent divs in the grid I have some little divs. I want these little divs to appear at the same height so they are aligned across the page. I think that I've given them the same relevant properties, but they are sitting at slightly different heights, and the line spacing is different. Why this is happening and how to remedy it?
Relevant info: I'm looking at my HTML in Chrome.
Image of my uneven blocks:
image of divs at uneven heights
Relevant code:
The container is defined in CSS like this:
.container {
width: 100%;
display: grid;
grid-template-columns: 1fr 2fr 2fr 4fr 1fr;
height: 400px;
background-color: lightgreen;
}
The two columns of the container where the problem arises are columns 3 and 4 (2fr and 4fr columns). Those divs are defined as:
.wordDisplay {
padding-top: 100px;
text-align: center;
}
.display {
padding-top: 100px;
}
And the little blue-box divs that I want to appear at the same height are:
.a {
display: inline-block;
width: 50px;
height: 50px;
padding-top: 20px;
margin: 1%;
border: 1px solid blue;
background-color: lightgreen;
font-size: 20px;
text-align: center;
}
.a:hover {
background-color: yellow !important;
}
.b {
display: inline-block;
width: 150px;
height: 50px;
padding-top: 20px;
margin: 1%;
border: 1px solid blue;
background-color: lightgreen;
font-size: 20px;
text-align: center;
}
.b:hover {
background-color: yellow;
}
Remove margins to get full height, The problem is, you're using margin for the wrong purpose
margin has different behavior, you have to be careful while using it.
Ask yourself why I want to use it here.
Your use of it as a value does not mean the expected result because it depends on your code scenario.
I recommend you to read this article
to ensure that you understand margins clearly, you will know what issue is happened
it's something dirty call margin collapse
there are two fixes I will recommend for your situation:
If your HTML like that:
<div class="container">
<div class="wordDisplay">
<div class="b">
band
</div>
<div class="b">
band
</div>
</div>
<div class="display">
<div class="a">
b
</div>
<div class="a">
a
</div>
<div class="a">
n
</div>
<div class="a">
d
</div>
<div class="a">
b
</div>
<div class="a">
a
</div>
<div class="a">
n
</div>
<div class="a">
d
</div>
</div>
</div>
Change margin for class "a" to half of margin in class "b" so if you add margin:1% in class "b" change the value of margin in class "a" to 0.5% so that will solve your problem.
Change grid template columns for column 3 and 4 to two equals fractions like that
.container {
width: 100%;
display: grid;
grid-template-columns: 1fr 2fr 4fr 4fr 1fr;
height: 400px;
background-color: lightgreen;
}

How to left-align items with each other in a grid that used justify-items: center

I am using grid. I centered my items but i want left position to be same on cross axis.
.box {
display: grid;
grid-template-columns: 1fr;
padding: 10px;
border: 1px solid blue;
gap: 1rem;
justify-items: center;
}
img {
width: 200px;
}
<div class="box">
<img src="img/featured.jpg">
<div class="item2">Item 2 Lorem</div>
</div>
Note : i want solution in only grid. There is many temporary fixes for that but i don't want that because i am looking for a perfect standard grid alignment solution for it.
You can do it a few ways:
1. Fixed Width Text (Not Responsive)
Based on the information you gave in your question. you can simply set the width of the item2 div to be the same as the image, e.g.:
.box {
display: grid;
grid-template-columns: 1fr;
padding: 10px;
border: 1px solid blue;
gap: 1rem;
justify-items: center;
}
.item2,
img {
width: 200px;
}
<div class="box">
<img src="https://via.placeholder.com/200x150">
<div class="item2">Item 2 Lorem</div>
</div>
2. The Responsive Way
This will allow us to responsively set up the 2 separate alignments you require: centre the container element, and left-align its contents, e.g.
<div class="box">
<div class="boxcontent">
Content here...
</div>
</div>
CSS: .boxcontent { text-align: left; }
Why this works:
You must have a defined relationship between the image and text, otherwise there is no way to tell the grid that these 2 individual elements must be positioned in relation to each other. You can do this by putting them in a container.
If you think about it, you are trying to do 2 separate alignments here:
make the image and text be centred in relation to the grid but also
make them be in alignment with each other so they are left aligned.
Putting them in a container achieves both of these objectives by creating a relationship between the image and text so that:
they act as a single unit in relation to the grid and also
allow them to be positioned in relation to each other regardless of the grid
Working Example:
.box {
display: grid;
grid-template-columns: 1fr;
padding: 10px;
border: 1px solid blue;
gap: 1rem;
justify-items: center;
}
.boxcontent {
text-align: left;
}
img {
width: 200px;
}
<div class="box">
<div class="boxcontent">
<img src="https://via.placeholder.com/200x150">
<div class="item2">Item 2 Lorem</div>
</div>
</div>
.box {
display: block;
margin: 0 auto;
width: max-content;
padding: 10px;
border: 1px solid blue;
}
img {
width: 200px;
}
.item2 {
margin-top: 1rem;
}
<div class="box">
<img src="pic_trulli.jpg" alt="Hi dear">
<div class="item2">Item 2 Lorem</div>
</div>

Grid element height affected by content image width percentage [duplicate]

This question already has answers here:
Prevent content from expanding grid items
(3 answers)
Why does minmax(0, 1fr) work for long elements while 1fr doesn't?
(1 answer)
Closed 2 years ago.
Edit: Let me clarify! I'm not asking about how to keep the content from flowing out by restricting the size of the container, what I'm looking for is how to properly adjust the size of the content based on the container and why a div with a background image set to cover works, while and img element does not.
I am trying to achieve a standard grid layout with a header, sidebar, content and footer, where the content element would have only a single image as a child, that should fill the entire remaining space. I thought that applying
img {
width: 100%;
height: 100%;
object-fit: cover;
}
would be enough to get the desired result, but it unexpectedly increased the height of the content element. What's even more absurd is that no matter how much I reduce the height of the image, as long as it is measured in percentages, the height of the container keeps depending on the width of the image. See the following pen (or look at the snippets below, but the issue is more apparent in the pen, since there the boxes are visible side-by-side) for example.
https://codepen.io/Isti115/pen/vYGRNpg
Try adjusting the .a img { widht: 100%; } and see how it affects the overall height.
.container {
display: inline-grid;
width: 400px;
height: 300px;
margin: 50px;
grid-template-rows: 75px 1fr 50px;
/* grid-template-rows: 75px minmax(0, 1fr) 50px; */
grid-template-columns: 100px 1fr;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
}
.header {
grid-area: header;
background-color: red;
}
.sidebar {
grid-area: sidebar;
background-color: yellow;
}
.content {
grid-area: content;
background-color: green;
}
.footer {
grid-area: footer;
background-color: blue;
}
.a .content {
/* min-height: 0; */
}
.a img {
width: 100%;
height: 20%;
/* object-fit: cover; */
/* height: 100%; */
}
.b img {
width: 100%;
height: 50px;
/* object-fit: cover; */
}
.c .placeholder {
width: 100%;
height: 100%;
/* background-color: purple; */
background: url("http://lorempixel.com/200/150/cats");
background-size: cover;
}
<div class="container a">
<div class="header"></div>
<div class="sidebar"></div>
<div class="content">
<img src="http://lorempixel.com/200/150/cats">
</div>
<div class="footer"></div>
</div>
<div class="container b">
<div class="header"></div>
<div class="sidebar"></div>
<div class="content">
<img src="http://lorempixel.com/200/150/cats">
</div>
<div class="footer"></div>
</div>
<div class="container c">
<div class="header"></div>
<div class="sidebar"></div>
<div class="content">
<div class="placeholder"></div>
</div>
<div class="footer"></div>
</div>
I have since found a solution by either adding min-height: 0 or using minmax(0, 1fr), but I don't consider those ideal solutions, since I don't see why I couldn't simply take the remaining space that gets assigned to the content div element and place an image inside it that fills it completely without expanding the containers size. For example using a simple div instead of the image and giving it a background works perfectly as intended.
ps.: I know that this might sound similar to some other questions that got answered with max-height: 100%, but I think that there is a more complicated underlying issue that I would like to explore.

css grid rows growing larger than intended

I'm interested in making responsive design with CSS grids, it looks promising. I've determined my dimensions as follows (to see if I can get the grid to do what I want):
.product-page-container {
display:grid;
grid-template-columns:2fr 2fr;
grid-template-rows:150px minmax(674px,675px) minmax(724px,725px) minmax(599px,600px) minmax(399px,400px) 150px;
grid-template-areas:
"banner banner"
"productHero productDetails"
"video video"
"features features"
"meta meta"
"footerBanner footerBanner"
}
In putting 'minmax' I assumed this would force my content to stay within this size. Which, in development, the rest of my website does not seem to be the case at all. The rows grow and shrink much past those limits or less. I
I'm fairly lost on how to achieve this. For example, my features area has a script that swaps out content. One block of contents ends up being 500px in height, and the next block of content ends up being 1200px in height, and the grid expands so it still is in the 'features' area, it's just the features area has expanded.
Is this just how grids work?
I'm having trouble observing what you're observing. Super ugly preview, I know, but scroll down to the green div. That's your features section. White div on the left is 500px height, and white div on the right is 1200px height (but you wouldn't know it since it's limited by the size of the .features div.
.product-page-container {
display:grid;
grid-template-columns:2fr 2fr;
grid-template-rows:150px 675px 725px 600px 400px 150px;
grid-template-areas:
"banner banner"
"productHero productDetails"
"video video"
"features features"
"meta meta"
"footerBanner footerBanner"
}
.banner {
grid-area: banner;
background-color: black;
}
.product-hero {
grid-area: productHero;
background-color: red;
}
.product-details {
grid-area: productDetails;
background-color: purple;
}
.video {
grid-area: video;
background-color: blue;
}
.features {
grid-area: features;
background-color: green;
}
.meta {
grid-area: meta;
background-color: yellow;
}
.footer-banner {
grid-area: footerBanner;
background-color: brown;
}
.small-content,
.large-content {
display: inline-block;
vertical-align: top;
margin: 20px;
width: 50px;
background-color: white;
}
.small-content {
height: 500px;
}
.large-content {
height: 1200px;
}
<div class="product-page-container">
<div class="banner"></div>
<div class="product-hero"></div>
<div class="product-details"></div>
<div class="video"></div>
<div class="features">
<div class="small-content"></div>
<div class="large-content"></div>
</div>
<div class="meta"></div>
<div class="footer-banner"></div>
</div>
Without more details it would be hard to replicate and debug, but alas:
THERE ARE SOME REASONS why your grid would behave in unexpected ways (including <pre> tags and large images). Chris Coyier wrote a great article on these problems and how to solve them here: https://css-tricks.com/preventing-a-grid-blowout/
I have a feeling that that article ^^ could contain your solution. Otherwise, try giving us more code to work from here. Good luck!