I'm trying to space out elements inside a Card evenly, but they are not lined-up:
here's the code:
<div className="card">
<header className="card-header">
<div className="card-header-info">
<p>{`#${driver.driverId}`}</p>
<h1>{driver.name}</h1>
</div>
<div className="card-header-info">
<p>VEHICLE</p>
<p>{driver.vehicleId}</p>
</div>
<div className="card-header-info">
<p>HOMETOWN</p>
<p>{driver.hometown}</p>
</div>
</header>
</div>
CSS
.card-header-info {
padding-left: 20px;
margin-right: auto;
}
I have also tried Bulma (CSS framework) columns but got nothing. Anyone know a slick technique that would achieve this goal while at the same time making the space relative to the size of the Card? I would appreciate any help.
I recommend the following for the header element using css grid:
.card-header {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
Related
I’d like to set up a page with multiple entries consisting of some description text and associated icons. The icons may vary in size and should be aligned. (I use letters “i” and “w” instead of icons for simplicity in my examples below.)
When the page is wide enough, I’d like them to be set up as a grid with a wide left column and the icons to the right, that should take as few horizontal space as possible. Here is an example with two “icons”.
.container {
display: grid;
grid-template-columns: 1fr repeat(2, max-content);
}
.content {
justify-self: center;
}
<div class="container">
<div class="header">Some text</div>
<div class="content">i</div>
<div class="content">i</div>
<div class="header">Some more text</div>
<div class="content">w</div>
<div class="content">w</div>
</div>
When the viewport is too small, so that the left column would be reduced, say, below 200 px, I’d like to switch responsively the layout and have it displayed as a stack, as in this example.
.container {
display: grid;
grid-template-columns: 1fr repeat(2, max-content) 1fr;
}
.container > div {
justify-self: center;
}
.header {
grid-column-start: 1;
grid-column-end: 5;
}
.content1 {
grid-column-start: 2;
}
.content2 {
grid-column-start: 3;
}
<div class="container">
<div class="header">Some text</div>
<div class="content1">i</div>
<div class="content2">i</div>
<div class="header">Some more text</div>
<div class="content1">w</div>
<div class="content2">w</div>
</div>
This approach works, but there are multiple aspects that I’d like to improve, if possible.
My web site uses bootstrap, so I could use their “row” and “col” functionalities (or other bootstrap concepts). Designing my own grid instead feels like not using the right tools for the job. But I could not find out how to design such a grid with bootstrap’s rows and columns. (This question raises a similar problem.)
My approach requires an explicit media query and uses two completely different designs depending on the available space. This feels more complex than necessary. Is it possible to make better use of the grid module responsiveness (or any other appropriate html or css trickery), so that the icons would automatically flow below the text when the viewport is too small? I thought about using auto-fill, but as my columns do not all have the same size, I ignore how to proceed.
My current design for the small viewport case uses classes content1, content2, and so on, and repetitive CSS instructions to place them in successive columns. This problem will be exacerbated if I want more icons. Can I avoid such repetition?
The display classes are responsive. Therefore you can use d-flex d-md-grid on the container. When it switches to display:flex the grid-template-columns will be ignored.
.container {
grid-template-columns: 1fr repeat(2, max-content);
}
.content {
justify-self: center;
}
<div class="container d-flex d-md-grid flex-wrap align-items-center justify-content-center text-md-start text-center">
<div class="header w-100">Some text</div>
<div class="content">i</div>
<div class="content">i</div>
<div class="header w-100">Some more text</div>
<div class="content">w</div>
<div class="content">w</div>
</div>
Demo on Codeply
Of course, you could use d-sm-grid, d-lg-grid or d-xl-grid instead of d-md-grid to set the breakpoint as desired.
I'm trying to arrange a set of statistics such that:
they are displayed on a single horizontal line
the enclosing element is no wider than it needs to be to contain the content
there should be a fixed gap between statistics
I tried implementing this using display: grid. Here is my approach:
.outer {
background-color: yellow;
display: inline-block;
}
.stats {
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
<div class="outer">
<div class="stats">
<div class="stat">
<strong>Value:</strong> 1,234,568
</div>
<div class="stat">
<strong>Another value:</strong> 98,765
</div>
<div class="stat">
<strong>Test value:</strong> 83,263
</div>
</div>
</div>
Unfortunately, this results in some strange overlapping. Despite there being plenty of room for the .outer element to expand, the statistics are wrapped over several lines and the text runs into other columns:
How can I avoid this problem? I tried adding:
.stat {
white-space: nowrap;
}
...but the text still "runs" together. What am I missing?
The main problem stems from this declaration:
grid-template-columns: repeat(auto-fit, minmax(0, 1fr))
You're setting the columns to shrink to zero width.
Also, 1fr does nothing here, because there is no free space in the container. (You have the primary container set to inline-block, i.e., min-width. This means no extra space.)
At a minimum, these commands appear to be confusing the inline-block algorithm.
Consider leaving the columns at auto width (a default setting).
And, perhaps, setting them to appear in the first row. (I used the grid-auto-flow: column technique.)
.outer {
background-color: yellow;
display: inline-block;
}
.stats {
display: grid;
grid-gap: 20px;
grid-auto-flow: column;
}
<div class="outer">
<div class="stats">
<div class="stat">
<strong>Value:</strong> 1,234,568
</div>
<div class="stat">
<strong>Another value:</strong> 98,765
</div>
<div class="stat">
<strong>Test value:</strong> 83,263
</div>
</div>
</div>
folks!
I m trying to create a widget qliksense card responsive but dont work its return one column always I need that work responsive em broke in another row in responsive mode.
Does Anybody knows?
<qw-console log="data">
<div class="container" ng-repeat="row in data.rows track by $index">
<div class=' sombra'>{{row.cells[0].qText}}</div>
<br/>
</div>
</qw-console>
my css has:
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
grid-template-rows: repeat(6, 100px) ;
grid-gap: 15px;
}
to resolve this question:
<qw-console log="data">
<div class="container">
<div ng-repeat="row in data.rows track by $index">
<div class=' sombra'>{{row.cells[0].qText}}</div>
<br/>
</div>
</div>
</qw-console>
Problem details
I wrote code like this. Here, the image should be spread by the space reserved by fr because thewidth, height, andobject-fit properties work. So I thought the text of the second .item would overflow.
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
In Firefox this causes text to run out,
Not so with Chrome.
Also, wrapping the image in a div element instead of just below the grid item will fix the problem.
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="item">
<div class="content">
<img src="https://unsplash.it/450/450">
</div>
</div>
<div class="item">
<div class="content">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
</div>
Unrelated but similar articles
I found a question that might be related, but I don't think this problem is related to my question because the source code of this question text works correctly in Firefox and Chrome.
Chrome / Safari not filling 100% height of flex parent
Heights rendering differently in Chrome and Firefox
Using 'height: 100%' and 'align-items: stretch' in flexbox
Why is my Grid element's height not being calculated correctly?
Unrelated but similar bugs
I also looked for related bug tickets, but these were already stated to have been fixed and may not be relevant to my problem.
https://bugs.chromium.org/p/chromium/issues/detail?id=426898
https://github.com/philipwalton/flexbugs/issues/197
Quesiton
Is this difference a bug without a bug ticket or undefined behavior?
If this is not an undefined behavior, which is the correct behavior?
If this is not an undefined behavior, which is the correct behavior?
I would say, Firefox is doing correctly here and Chrome is half correct.
First, you can reduce your code to the following as grid-template-rows: 1fr is not needed to have the behavior
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
Then you can use any percentage value (either smaller or bigger than 100%) and you will see that chrome will do nothing in the second case where we have text:
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 50%;
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
As I explained here you are facing a particular behavior of percentage height. By default percentage height is relative to the explicit height of the containing block and in our case we didn't set any explicit height to our row (1fr isn't explicit). Considering the CSS2 specification we should fail to auto
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 value computes to 'auto'. ref
Chrome is doing this with the second image. It consider the height to be auto which is not completely wrong.
In the CSS3 specification we have another section that allow the browser to do more effort:
Sometimes the size of a percentage-sized box’s containing block depends on the intrinsic size contribution of the box itself, creating a cyclic dependency. When calculating the intrinsic size contribution of such a box (including any calculations for a content-based automatic minimum size), a cyclic percentage—that is, a percentage value that would resolve against a containing block size which itself depends on that percentage—is resolved specially: ref
Then you have a set of complex rules and the two importants parts are:
Otherwise, the percentage is resolved against the containing block’s size. (The containing block’s size is not re-resolved based on the resulting size of the box; the contents might thus overflow or underflow the containing block).
And one rule with the note:
Note: Grid items and flex items do allow percentages to resolve in this case.
To make it easy, the browser will first ignore the percentage height to calculate the height of each grid track based on the content to have the following:
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
/*height: 100%;*/
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
Then considering the previous calculated height of grid track we resolve the percentage height to get the following and we don't get back to recalculate the height of the track again:
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
The text will logically overflow since the height was defined by the image+text and we told to the image to take all the height making the text outside and making the image filling all the space.
Using any percentage value will give the same result which is make the image X% of the height defined by the image+text.
Setting an explicit height will make both behave the same since we have no complex calculation and we can rely on the CSS2 part of the specification:
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows:200px;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
Adding an extra wrapper will make the height fail to auto in all the cases as it become more complex1 for browsers to handle such case.
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 958%;
object-fit: cover;
}
<div class="container">
<div class="item">
<div>
<img src="https://unsplash.it/450/450">
</div>
</div>
<div class="item">
<div>
<img src="https://unsplash.it/450/450">
</div>
text
</div>
</div>
Adding height:100% to the extra wrapper will put as back to the previous cases and height can be resolved again:
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 50%;
object-fit: cover;
}
.item>div {
height: 100%;
}
<div class="container">
<div class="item">
<div>
<img src="https://unsplash.it/450/450">
</div>
</div>
<div class="item">
<div>
<img src="https://unsplash.it/450/450">
</div>
text
</div>
</div>
In this case, the div is taking the height defined by the image+text (the text will overflow) then the image inside the div will take half that height.
Related questions with similar situations:
https://stackoverflow.com/a/52137966/8620333
Chrome / Firefox percentage height differences in CSS Grid
Grid gap percentage without height
1: I won't be able to give the exact part explaining why we cannot resolve in this case.
I'm trying to create a CSS Grid which centers all its items both horizontally and vertically and maintains a background which takes up the whole grid.
To do this, I am first creating CSS for each item which looks something like this:
.item1 {
grid-area: header;
background:yellow;
text-align: center;
align-items: center;
display: grid;
}
The only difference between each item is its item number (in the class), the grid-area name, and the background color. I added display: grid; because without it I can't seem to both center and have the background color cover the whole grid. I don't understand why this is, but it seems to work.
My container CSS looks like this:
.container {
display: grid;
grid-template-columns: 20vw 20vw 20vw 20vw;
grid-template-rows: 25vh 25vh 25vh;
grid-template-areas:
"header header header header"
"main main subg sidebar"
"footer footer footer footer";
}
Now when I create the grid everything looks the way I want it to:
<div class="container">
<div class="item1"><H1>Header</H1></div>
<div class="item2">Main</div>
<div class="item3">Sidebar</div>
<div class="item4">Footer</div>
<div class="item5">X</div>
</div>
Now I want to achieve the exact same effect in the central item. So first I create nearly identical CSS tags for the sub-items and sub-containers. The only differences are in the naming and changing the dimensions from absolute screen based (vh/vw) to percentages:
.sub_item1 {
grid-area: header1;
background:yellow;
text-align: center;
align-items: center;
display: grid;
}
...
.sub_container {
display: grid;
grid-template-columns: 25% 25% 25% 25%;
grid-template-rows: 33% 33% 33%;
grid-template-areas:
"header1 header1 header1 header1"
"main1 main1 subg1 sidebar1"
"footer1 footer1 footer1 footer1";
}
I nest the sub-container in the center item in the top-level container:
<div class="container">
<div class="item1"><H1>Header</H1></div>
<div class="item2">Main</div>
<div class="item3">Sidebar</div>
<div class="item4">Footer</div>
<div class="item5 sub_container">
<div class="sub_item1">Header</div>
<div class="sub_item2">Main</div>
<div class="sub_item3">Side</div>
<div class="sub_item4">Footer</div>
<div class="sub_item5">X</div>
</div>
</div>
I have created a fiddle to demonstrate how it fails. The sub-container does not stretch the background color to fit the cells like the top-level does.
I tried changing the dimensions to screen based (e.g. 5vw, 11vh) and this does not work either.
Remove the "item5" class from the sub-container div.
<div class="sub_container">
Here is the updated fiddle.