max-width css grid container not taking up 100% of parent container - css

I am trying out css-grid but I am having some trouble with content taking up 100% of parent container. I am absolutely lost. I have a max-width: 1200px on the content in my layouts/index.js file. I then call grid-template-columns: 1fr in the child Component. The child component background-image does not take up 1200px but rather 423px. The image is 2600px wide. I thought 1fr would take up all the space of the max-width content container. What am I missing?
layouts/index.js
const Wrapper = styled.div`
display: grid;
grid-template-rows: auto 1fr auto;
background: red;
height: 100vh;
overflow-y: auto;
`;
const Content = styled.div`
max-width: 1200px;
background: pink;
padding-top: 2rem;
${media.desktop`padding: 2rem ;`}
${media.tablet`padding: 2.4rem;`}
${media.phone`padding: 1.2rem;`}
margin: 0 auto;
`;
const LayoutWrapper = ({ children }) => (
<Wrapper>
<Helmet
title="Fouts Tax Service"
meta={[
{ name: 'description', content: 'A tax service in Anderson, Indiana run by Jerry Fouts' },
{ name: 'keywords', content: 'tax, anderson, 46011, indiana, service, fouts,' },
]}
/>
<ResponsiveHeader/>
<Content>
{children()}
</Content>
<Footer/>
</Wrapper>
);
pages/index.js
import HeroImg from '../images/taxes.jpg'
const Grid = styled.div`
display: grid;
grid-template-columns: 1fr;
border: 2px solid black;
grid-gap: 10px;
align-content: center;
`;
const Showcase = styled.div`
background-image: url(${HeroImg});
background-size: cover;
background-position: center;
background-repeat: no-repeat;
background-color: #a7a7a7;
background-blend-mode: color-burn;
grid-gap: 10px;
padding: 4rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: start;
class IndexPage extends Component {
render() {
return (
<Grid>
<Showcase>
<h1>Fouts Tax Service</h1>
<h3>Year round tax service</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing.</p>
</Showcase>
</Grid>
)
}
}
Here is a picture of what I am talking about.

You can also try adding min-width: 0; to grid-items.

I faced the same error while using the following
<grid-element>
<angular-component>
<swiper>
<!-- ... -->
<img src="yourImage.jpg">
<!-- ... -->
</swiper>
</angular-component>
</grid-element>
I tried the answer from #janisKonutis and it worked
grid-element {
display: grid
> * {
min-width: 0; // <-- This did fix the problem
}
}
But I was interested to know why. the nice css-tricks.com propose a bunch of possible fixes
Explanation from Chris Coyier
I can’t promise I’m explaining this 100% accurately, but the way I understand it, the minimum width of a grid column is auto. (The same is true for flex items, by the way.)
And since auto is entirely based on content, we can say it is “indefinitely” sized, its dimensions flex. If we were to put an explicit width on the column, like 50% or 400px, then we would say it is “definitely” sized.
To apply our fix, we need to make sure that there is the column has a definite minimum width instead of auto.

Related

Images aspect ratio distorted when making 100% height/width of container

I have this style:
.album-photos-container {
position: relative;
display: flex;
flex-flow: wrap;
justify-content: center;
.image-card-small {
width: 48%;
margin: 4px;
filter: brightness(0.8);
img {
width: 100%;
height: 100%;
max-height: 400px;
}
}
}
This is what it looks like with images getting distorted.
I read about the display: flex; and flex-flow: wrap; and it looks this is what they do and I need some other approach maybe.
I try to set the max-height: 400px; to a higher value like 2000 then it looks like this:
Please advise: I want images to fill the box no matter how wide or tall the image is!
UPDATE
Here is the component
import React from 'react'
const ClickablePhoto = (props) => {
return (
<div onClick={props.onClick} className="image-card-small">
<img src={props.src} id={props.id} alt="album" />
</div>
)
}
export default ClickablePhoto
And I tried like this:
return (
<div onClick={props.onClick} style={{backgroundImage: 'url(' + require(`${props.src}`) + ') background-size: cover'} } >
<img src={props.src} id={props.id} alt="album" />
</div>
)
But the image src from the props looks like this: /static/media/0_sJ1A5jGwSm66KCdV.e2451a3a.png and background-image: url cant find the image
You can't crop images with <img> element.
You could use div with background-image:
<div class="image" style="background-image: url(...); background-size: cover;" />

Angular GoogleMaps Marker InfoWindow scrollbar not getting hidden

I'm trying to customise the popup info window that appears when you click on a marker, but I can't get rid of the scrollbar that appears on the right in case the content overflows.
https://pasteboard.co/Ith8X2v.png (image was not loading when used the image template)
I've tried adding overflow: scroll too all the parent containers as it seems that's the only thing the was different (see this).
I've made a little clip with what kinda worked but not entirely.
https://streamable.com/guoei
Markers code:
<agm-marker *ngFor="let m of markers; let i = index"
(markerClick)="clickedMarker(m.label, i)"
[latitude]="m.lat"
[longitude]="m.lng"
[label]="m.label"
[markerDraggable]="m.draggable">
<agm-info-window>
<div class="popup-info-container">
<div class="popup-header-container">
<strong>InfoWindow content</strong>
</div>
<div class="popup-body-container">
<strong>InfoWindow content</strong>
</div>
</div>
</agm-info-window>
</agm-marker>
CSS code:
.popup-info-container {
height: 400px;
width: 300px;
background-color: red;
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
&::-webkit-scrollbar {
display: none;
}
}
.agm-info-window-content {
overflow: scroll;
}
.popup-header-container {
height: 20%;
width: 95%;
background-color: blue;
}
.popup-body-container {
height: 75%;
width: 95%;
background-color:whitesmoke;
}
I want to get something like this:
where the scrollbar fadesout.
I've found a similar thing here How to edit css of child component imported from other module Angular 2+
Basically I had to override classes that angular was generating with ::ng-deep
::ng-deep .gm-style {
.gm-style-iw-d::-webkit-scrollbar {
display: none !important;
}
}

CSS Grid vertical columns with infinite rows

I have a list of items of unknown length (from a CMS). I want to display them in 2 vertical columns reading down. e.g.
1 4
2 5
3 6
etc...
I am trying to achieve this with CSS grid, however, it doesn't seem possible unless you set the number of rows up front. I have tried grid-auto-flow: column as per https://gridbyexample.com/examples/example18/ but this just adds additional columns when it gets to the end.
I feel like this should be possible with grid, but I can't find a way. Anyone have any ideas?
P.S. Please don't suggest CSS text columns.
Without knowing the exact amount of items this is not possible with CSS grid alone.
The only way to get around this limitation is to add a class to your second half of the items.
body {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-flow: row dense;
/* extra styles */
grid-gap: 0.5rem;
}
span {
grid-column-start: 1;
/* extra styles */
background-color: #def;
padding: 0.5rem;
}
.second-half {
grid-column-start: 2;
/* extra styles */
background-color: #abc;
}
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span class="second-half">5</span>
<span class="second-half">6</span>
<span class="second-half">7</span>
Example:
// This is just to simulate infinite scrolling
var counter = 9;
document.addEventListener('scroll', function(e) {
if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
var span = document.createElement('span');
span.innerHTML = ++counter;
document.body.appendChild(span);
}
})
body {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 200px;
/* how much height must each element occupy! change that! */
grid-gap: 0.5rem;
}
span {
background: #3A3A3A;
text-align: center;
color: #FFFFFF;
line-height: 200px;
font-size: xx-large;
}
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
<span>8</span>
One solution if your HTML is generated you can calculate the grid-template-rows property on the container element with Math.ceil( NUM_ITEMS / NUM_COLUMNS )
In React:
function VerticalColumns(props) {
// props.numColumns matches `grid-template-columns` on `.container` element
const numRows = Math.ceil(props.items.length / props.numColumns);
const style = {
gridTemplateRows: `repeat(${numRows}, 1fr)`,
};
return (
<ul className='container' style={ style }>
{ props.items.map((item, index) => (
<li key={index}>{ item }</li>
)) }
</ul>
)
}
Base CSS:
.container {
display: grid;
grid-auto-flow: column;
grid-template-columns: repeat(2, 1fr);
}
You can use a flex in which there is a container and a flex item. You can limit the height of the container and then wrap the contents of flex to continue in the next column :-
<body>
<div class="container">
<p>1</p>
<p>1</p>
<p>1</p>
<p>1</p>
<p>1</p>
</div>
</body>
CSS:
.container {
height: 300px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
Read more about flexbox

Horizontal center for flex items [duplicate]

I want the flex items to be centered but when we have a second line, to have 5 (from image below) under 1 and not centered in the parent.
Here's an example of what I have:
ul {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
margin: 0;
padding: 0;
}
li {
list-style-type: none;
border: 1px solid gray;
margin: 15px;
padding: 5px;
width: 200px;
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
http://jsfiddle.net/8jqbjese/2/
Flexbox Challenge & Limitation
The challenge is to center a group of flex items and left-align them on wrap. But unless there is a fixed number of boxes per row, and each box is fixed-width, this is currently not possible with flexbox.
Using the code posted in the question, we could create a new flex container that wraps the current flex container (ul), which would allow us to center the ul with justify-content: center.
Then the flex items of the ul could be left-aligned with justify-content: flex-start.
#container {
display: flex;
justify-content: center;
}
ul {
display: flex;
justify-content: flex-start;
}
This creates a centered group of left-aligned flex items.
The problem with this method is that at certain screen sizes there will be a gap on the right of the ul, making it no longer appear centered.
This happens because in flex layout (and, actually, CSS in general) the container:
doesn't know when an element wraps;
doesn't know that a previously occupied space is now empty, and
doesn't recalculate its width to shrink-wrap the narrower layout.
The maximum length of the whitespace on the right is the length of the flex item that the container was expecting to be there.
In the following demo, by re-sizing the window horizontally, you can see the whitespace come and go.
DEMO
A More Practical Approach
The desired layout can be achieved without flexbox using inline-block and media queries.
HTML
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
CSS
ul {
margin: 0 auto; /* center container */
width: 1200px;
padding-left: 0; /* remove list padding */
font-size: 0; /* remove inline-block white space;
see https://stackoverflow.com/a/32801275/3597276 */
}
li {
display: inline-block;
font-size: 18px; /* restore font size removed in container */
list-style-type: none;
width: 150px;
height: 50px;
line-height: 50px;
margin: 15px 25px;
box-sizing: border-box;
text-align: center;
}
#media screen and (max-width: 430px) { ul { width: 200px; } }
#media screen and (min-width: 431px) and (max-width: 630px) { ul { width: 400px; } }
#media screen and (min-width: 631px) and (max-width: 830px) { ul { width:600px; } }
#media screen and (min-width: 831px) and (max-width: 1030px) { ul { width: 800px; } }
#media screen and (min-width: 1031px) and (max-width: 1230px) { ul { width: 1000px; } }
The above code renders a horizontally-centered container with left-aligned child elements like this:
DEMO
Other Options
Properly sizing and aligning the flex item(s) on the last row
Desandro Masonry
Masonry is a JavaScript grid layout library. It
works by placing elements in optimal position based on available
vertical space, sort of like a mason fitting stones in a wall. You’ve
probably seen it in use all over the Internet.
source: http://masonry.desandro.com/
CSS Grid Layout Module Level 1
This CSS module defines a two-dimensional grid-based layout system, optimized for user interface design. In the grid layout model, the children of a grid container can be positioned into arbitrary slots in a predefined flexible or fixed-size layout grid.
source: https://drafts.csswg.org/css-grid/
You can achieve it with CSS Grid, just use repeat(autofit, minmax(width-of-the-element, max-content))
ul {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(210px, max-content));
grid-gap: 16px;
justify-content: center;
padding: initial;
}
li {
list-style-type: none;
border: 1px solid gray;
padding: 5px;
width: 210px;
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
</ul>
http://jsfiddle.net/rwa20jkh/
Somehow, #Joe82 answer did not work for me. However, I found it to be the right approach. After reading this article about auto-fit and auto-fill I found out that auto-fit creates new columns when possible; however, it collapses them, so that the grid-items fill out the whole available space, if their max-width allows them this.
For those interested: auto-fill also creates new columns when possible, but does not let them collapse, so it creates empty visible columns, which will take up space.
You can see this in the following image:
Because of this, I used repeat(auto-fit, minmax(10rem, 1fr) for `grid-template-columns.
Then I set justify-items to center, this aligns the items inside their grid areas on the inline axis.
I also wanted some "margins" between the columns and rows, so I added a row-gap and a column-gap of 1rem with the shorthand.
As a result I added the following CSS to my div with the grid items inside it:
.card-section {
width: 100%;
display: grid;
justify-items: center;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}
I know this is not exactly what OP wanted to achieve, but maybe it helps someone, who has the same problem as me and stumbles upon this question.
You can place invisible elements with the same class as the others (removed on example for exibition purposes) and height set to 0. With that, you will be able to justify the items to the very start of the grid.
Example
<div class="table-container">
<div class="table-content">
<p class="table-title">Table 1</p>
<p class="mesa-price">$ 20</p>
</div>
<!-- Make stuff justified start -->
<div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
<div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
<div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
<div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
</div>
Result
As #michael suggested, this is a limitation with current flexbox. But if you want to still use flex and justify-content: center;, then we can workaround this by adding a dummy li element and assign margin-left.
const handleResize = () => {
const item_box = document.getElementById('parentId')
const list_length = item_box.clientWidth
const product_card_length = 200 // length of your child element
const item_in_a_row = Math.round(list_length/product_card_length)
const to_be_added = item_in_a_row - parseInt(listObject.length % item_in_a_row) // listObject is the total number items
const left_to_set = (to_be_added - 1 ) * product_card_length // -1 : dummy item has width set, so exclude it when calculating the left margin
const dummy_product = document.querySelectorAll('.product-card.dummy')[0]
dummy_product.style.marginLeft = `${left_to_set}px`
}
handleResize() // Call it first time component mount
window.addEventListener("resize", handleResize);
Check this fiddle (resize and see ) or video for reference
One way to get the desired style with margins is to do the following:
#container {
display: flex;
justify-content: center;
}
#innercontainer {
display: flex;
flex: 0.9; -> add desired % of margin
justify-content: flex-start;
}
I ran into this problem while coding with React Native. There's an elegant solution that you can have using FlexBox. In my particular situation, I was trying to center three flex boxes (Flex: 2) inside another using alignItems. The solution I came up with was using two empty s, each with Flex: 1.
<View style={{alignItems: 'center', flexWrap: 'wrap', flexDirection: 'row'}}>
<View style={{flex: 1}} />
// Content here
<View style={{flex: 1}} />
</View>
Easy enough to convert to web / CSS.
The easiest way I've found to fix this is just simply add some place holders with visibility: hidden. That way it maintains the correct spacing as it wraps.
TL;DR
You can stuff some filler elements to the end of your container, and set visibility: hidden to make it invisible, and remember to set height: 0px to prevent the height be taken.
Demo
In the example below, you can click the button to watch the changes.
const container = document.getElementsByClassName('container')[0];
const item = document.createElement('div');
item.classList.add("item");
const filler = document.createElement('div')
filler.classList.add("filler");
item.appendChild(filler);
Array.from(Array(5).keys()).forEach(() => {
container.appendChild(item.cloneNode(true));
});
function onShowClick() {
const filler = document.getElementsByClassName('filler')
for (let i = 0; i < filler.length; i++) {
filler[i].style.border = "1px dashed #686868"
filler[i].style.visibility = "visible"
filler[i].style.height = "100px"
}
};
function onHideClick() {
const filler = document.getElementsByClassName('filler')
for (let i = 0; i < filler.length; i++) {
filler[i].style.border = "none"
filler[i].style.visibility = "hidden"
filler[i].style.height = "0px"
}
};
* {
box-sizing: border-box;
}
#root {
height: 400px;
width: 500px;
border: 1px solid #ff955a;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.item {
padding: 5px;
}
.content-box {
height: 100px;
width: 100px;
padding: 10px;
background-color: lightblue;
border-radius: 10px;
}
.filler {
visibility: hidden;
height: 0px;
width: 100px;
}
<div id="root">
<button onclick="onShowClick()">Show</button>
<button onclick="onHideClick()">Hide</button>
<div class="container">
<div class="item">
<div class="content-box">1</div>
</div>
<div class="item">
<div class="content-box">2</div>
</div>
<div class="item">
<div class="content-box">3</div>
</div>
<div class="item">
<div class="content-box">4</div>
</div>
<div class="item">
<div class="content-box">5</div>
</div>
<div class="item">
<div class="content-box">6</div>
</div>
<div class="item">
<div class="content-box">7</div>
</div>
<div class="item">
<div class="content-box">8</div>
</div>
<div class="item">
<div class="content-box">9</div>
</div>
</div>
</div>

Flexbox quirks, centering of grid [duplicate]

I want the flex items to be centered but when we have a second line, to have 5 (from image below) under 1 and not centered in the parent.
Here's an example of what I have:
ul {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
margin: 0;
padding: 0;
}
li {
list-style-type: none;
border: 1px solid gray;
margin: 15px;
padding: 5px;
width: 200px;
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
http://jsfiddle.net/8jqbjese/2/
Flexbox Challenge & Limitation
The challenge is to center a group of flex items and left-align them on wrap. But unless there is a fixed number of boxes per row, and each box is fixed-width, this is currently not possible with flexbox.
Using the code posted in the question, we could create a new flex container that wraps the current flex container (ul), which would allow us to center the ul with justify-content: center.
Then the flex items of the ul could be left-aligned with justify-content: flex-start.
#container {
display: flex;
justify-content: center;
}
ul {
display: flex;
justify-content: flex-start;
}
This creates a centered group of left-aligned flex items.
The problem with this method is that at certain screen sizes there will be a gap on the right of the ul, making it no longer appear centered.
This happens because in flex layout (and, actually, CSS in general) the container:
doesn't know when an element wraps;
doesn't know that a previously occupied space is now empty, and
doesn't recalculate its width to shrink-wrap the narrower layout.
The maximum length of the whitespace on the right is the length of the flex item that the container was expecting to be there.
In the following demo, by re-sizing the window horizontally, you can see the whitespace come and go.
DEMO
A More Practical Approach
The desired layout can be achieved without flexbox using inline-block and media queries.
HTML
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
CSS
ul {
margin: 0 auto; /* center container */
width: 1200px;
padding-left: 0; /* remove list padding */
font-size: 0; /* remove inline-block white space;
see https://stackoverflow.com/a/32801275/3597276 */
}
li {
display: inline-block;
font-size: 18px; /* restore font size removed in container */
list-style-type: none;
width: 150px;
height: 50px;
line-height: 50px;
margin: 15px 25px;
box-sizing: border-box;
text-align: center;
}
#media screen and (max-width: 430px) { ul { width: 200px; } }
#media screen and (min-width: 431px) and (max-width: 630px) { ul { width: 400px; } }
#media screen and (min-width: 631px) and (max-width: 830px) { ul { width:600px; } }
#media screen and (min-width: 831px) and (max-width: 1030px) { ul { width: 800px; } }
#media screen and (min-width: 1031px) and (max-width: 1230px) { ul { width: 1000px; } }
The above code renders a horizontally-centered container with left-aligned child elements like this:
DEMO
Other Options
Properly sizing and aligning the flex item(s) on the last row
Desandro Masonry
Masonry is a JavaScript grid layout library. It
works by placing elements in optimal position based on available
vertical space, sort of like a mason fitting stones in a wall. You’ve
probably seen it in use all over the Internet.
source: http://masonry.desandro.com/
CSS Grid Layout Module Level 1
This CSS module defines a two-dimensional grid-based layout system, optimized for user interface design. In the grid layout model, the children of a grid container can be positioned into arbitrary slots in a predefined flexible or fixed-size layout grid.
source: https://drafts.csswg.org/css-grid/
You can achieve it with CSS Grid, just use repeat(autofit, minmax(width-of-the-element, max-content))
ul {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(210px, max-content));
grid-gap: 16px;
justify-content: center;
padding: initial;
}
li {
list-style-type: none;
border: 1px solid gray;
padding: 5px;
width: 210px;
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
</ul>
http://jsfiddle.net/rwa20jkh/
Somehow, #Joe82 answer did not work for me. However, I found it to be the right approach. After reading this article about auto-fit and auto-fill I found out that auto-fit creates new columns when possible; however, it collapses them, so that the grid-items fill out the whole available space, if their max-width allows them this.
For those interested: auto-fill also creates new columns when possible, but does not let them collapse, so it creates empty visible columns, which will take up space.
You can see this in the following image:
Because of this, I used repeat(auto-fit, minmax(10rem, 1fr) for `grid-template-columns.
Then I set justify-items to center, this aligns the items inside their grid areas on the inline axis.
I also wanted some "margins" between the columns and rows, so I added a row-gap and a column-gap of 1rem with the shorthand.
As a result I added the following CSS to my div with the grid items inside it:
.card-section {
width: 100%;
display: grid;
justify-items: center;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}
I know this is not exactly what OP wanted to achieve, but maybe it helps someone, who has the same problem as me and stumbles upon this question.
You can place invisible elements with the same class as the others (removed on example for exibition purposes) and height set to 0. With that, you will be able to justify the items to the very start of the grid.
Example
<div class="table-container">
<div class="table-content">
<p class="table-title">Table 1</p>
<p class="mesa-price">$ 20</p>
</div>
<!-- Make stuff justified start -->
<div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
<div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
<div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
<div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
</div>
Result
As #michael suggested, this is a limitation with current flexbox. But if you want to still use flex and justify-content: center;, then we can workaround this by adding a dummy li element and assign margin-left.
const handleResize = () => {
const item_box = document.getElementById('parentId')
const list_length = item_box.clientWidth
const product_card_length = 200 // length of your child element
const item_in_a_row = Math.round(list_length/product_card_length)
const to_be_added = item_in_a_row - parseInt(listObject.length % item_in_a_row) // listObject is the total number items
const left_to_set = (to_be_added - 1 ) * product_card_length // -1 : dummy item has width set, so exclude it when calculating the left margin
const dummy_product = document.querySelectorAll('.product-card.dummy')[0]
dummy_product.style.marginLeft = `${left_to_set}px`
}
handleResize() // Call it first time component mount
window.addEventListener("resize", handleResize);
Check this fiddle (resize and see ) or video for reference
One way to get the desired style with margins is to do the following:
#container {
display: flex;
justify-content: center;
}
#innercontainer {
display: flex;
flex: 0.9; -> add desired % of margin
justify-content: flex-start;
}
I ran into this problem while coding with React Native. There's an elegant solution that you can have using FlexBox. In my particular situation, I was trying to center three flex boxes (Flex: 2) inside another using alignItems. The solution I came up with was using two empty s, each with Flex: 1.
<View style={{alignItems: 'center', flexWrap: 'wrap', flexDirection: 'row'}}>
<View style={{flex: 1}} />
// Content here
<View style={{flex: 1}} />
</View>
Easy enough to convert to web / CSS.
The easiest way I've found to fix this is just simply add some place holders with visibility: hidden. That way it maintains the correct spacing as it wraps.
TL;DR
You can stuff some filler elements to the end of your container, and set visibility: hidden to make it invisible, and remember to set height: 0px to prevent the height be taken.
Demo
In the example below, you can click the button to watch the changes.
const container = document.getElementsByClassName('container')[0];
const item = document.createElement('div');
item.classList.add("item");
const filler = document.createElement('div')
filler.classList.add("filler");
item.appendChild(filler);
Array.from(Array(5).keys()).forEach(() => {
container.appendChild(item.cloneNode(true));
});
function onShowClick() {
const filler = document.getElementsByClassName('filler')
for (let i = 0; i < filler.length; i++) {
filler[i].style.border = "1px dashed #686868"
filler[i].style.visibility = "visible"
filler[i].style.height = "100px"
}
};
function onHideClick() {
const filler = document.getElementsByClassName('filler')
for (let i = 0; i < filler.length; i++) {
filler[i].style.border = "none"
filler[i].style.visibility = "hidden"
filler[i].style.height = "0px"
}
};
* {
box-sizing: border-box;
}
#root {
height: 400px;
width: 500px;
border: 1px solid #ff955a;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.item {
padding: 5px;
}
.content-box {
height: 100px;
width: 100px;
padding: 10px;
background-color: lightblue;
border-radius: 10px;
}
.filler {
visibility: hidden;
height: 0px;
width: 100px;
}
<div id="root">
<button onclick="onShowClick()">Show</button>
<button onclick="onHideClick()">Hide</button>
<div class="container">
<div class="item">
<div class="content-box">1</div>
</div>
<div class="item">
<div class="content-box">2</div>
</div>
<div class="item">
<div class="content-box">3</div>
</div>
<div class="item">
<div class="content-box">4</div>
</div>
<div class="item">
<div class="content-box">5</div>
</div>
<div class="item">
<div class="content-box">6</div>
</div>
<div class="item">
<div class="content-box">7</div>
</div>
<div class="item">
<div class="content-box">8</div>
</div>
<div class="item">
<div class="content-box">9</div>
</div>
</div>
</div>

Resources