swiper: CSS Grid + Swiper Wrapper - wrong width calculated
This is a (multiple allowed):
-
bug
-
enhancement
-
feature-discussion (RFC)
-
Swiper Version: 4.4.2 from CDNJS
-
Platform/Target and Browser Versions: Latest Chrome on macOS (confirmed issue is happening in Latest Safari also)
-
Live Link or JSFiddle/Codepen or website with isssue: https://codepen.io/anon/pen/pqJBWX (Also raised with others: https://codepen.io/meredevelopment/pen/yorRMm and here on your forums: http://idangero.us/swiper/forum/#!/?css grid)
What you did
A basic CSS grid setup with 3 columns setup on a wrapper. Carousel is set up within the 3rd column with a width of 1fr (which should take up 1fr of the remaining space of the max-width container). For code example see codepen showing issue. Code is direct replica of code in my development build.
Expected Behavior
Swiper wrapper is to take up the remaining space of the container instead of overflowing with the correct slidesPerView
visible
Actual Behavior
Swiper wrapper is overflowing, with slidersPerView
being ignored. Wrapper is showing width of entire width of elements.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 33
- Comments: 42 (2 by maintainers)
Commits related to this issue
- fix(testimonials): remove grid property on the mobile viewport due to the bug in swiper https://github.com/nolimits4web/swiper/issues/2914 — committed to in-in/helium by in-in 5 years ago
- Fix issue with overflow content from jetpack carousel. Still not working on archive pages, due to bug of swiper lib: https://github.com/nolimits4web/swiper/issues/2914 Also add proper page title fo... — committed to elightup/estar by rilwis 4 years ago
I had a similar issue and found a solution.
You can prevent Swiper from overflowing by adding an
overflow: hidden
to the parent element (in your case the.wrapper
).And there was also an issue with your grid column setup.
.sidebar
should have a value of1 / 2
and.carousel
a value of2 / 3
.I updated your Codepen example: https://codepen.io/anon/pen/MdmxNp
instead of ‘auto’ in grid-column definition, you can use ‘minmax(0, auto)’. the column width gets calculated in pixel, so the swiper calculates its width correctly.
One more workaround to add, as I’ve noticed something specific. If I have a 2-column grid (using
grid-template-columns: 1fr 1fr
), the crucial part is that the immediate child in the column must haveoverflow: hidden
. Then, Swiper will calculate its width correctly no matter how far nested it is.If the immediate child of the column is not set to overflow hidden, the width won’t be calculated correctly
This will break:
Right now solution is using
minmax(0, 1fr)
instead of1fr
.My workaround to solve this problem for a single-slide slider that placed inside flex item.
Tested in Swiper 6.4.8
For me, it worked to wrap the slider with an additional
display: grid
element and set swiper-container to 100% width. codepen as demo: https://codepen.io/_Mellow/pen/KKmRwzwAt the very least, there should be a “Gotchas” section, or something to that effect added to the documentation that notes this blatant issue. I can imagine many people, like myself, pulled their hair out for far, far too long thinking something was wrong with our setup.
In my case, it was a basic flex layout. Adding
overflow: hidden
to the parent did fix the issue immediately.Still happening… Swiper goes bonkers if it’s in a Grid with FR units.
When changing grid-template-columns to percentage instead fr, it works, but makes the “grid gaps” calculation more tedious this way.
Almost a year later and grid is a best practice. It would really help if this issue would not exist anymore. 😃
The fix from https://github.com/nolimits4web/swiper/issues/2914#issuecomment-493384617 worked like a charm nonetheless!
And of course, thank you for swiper, it works really well, and kudos for the good docs!
I got the same issue and the
overflow: hidden
trick doesn’t work. I think the problem is similar to what @suxscribe described. I set the layout usingfr
, notpx
.This is my screenshot: https://prnt.sc/ry8y59
Just to contribute to the catalog of workarounds: in my case I was using only a single column in the grid, so I instead of using the default value for
grid-template-columns
, I explicitly set it togrid-template-columns: 100%;
and it worked wonders, thank you guys 😉wasted hours until found the display grid on parent was growing swiper width and some times height to infinity. Used this to fix it but feels scared what if people get that bug in their browser or device for whatever reason
display: grid; grid-template-columns: minmax(0, 1fr);
Your solution only works if you set width of some column in ‘px’. If columns are set in ‘fr’ swiper takes all the space and goes into infinity (I have 6-digit numbers in ‘translate3d’ property of the slides)
In such layout, there is no clear way in this case to detect available “cell” width -> so swiper can’t calculate its own and slides size. You can fix this current layout but changing
width: 100vw
on.carousel
or by using flex instead of gridI had this problem on iOS 12 but
overflow: hidden
wasn’t enough.So, in place of this
grid-template-columns: 6fr 6fr;
I used this
grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
and it worked.
This is the one that fixes swiper slider from making wrong calculations in the order of exponents.
Very helpful content here, thanks! Adding my case here if anyone will have sth similar
The solution was to add this to
GridArea1
styles - the element is a block itself, but is a part of the grid:Was able to come up with this after reading this StackOverflow answer.
I had 2 different scenarios, both kind of relating to what I raised in #4993
Scenario 1
Parent element with display grid and 1 column. Swiper deep nested inside of it.
The problem here across all browsers was that swiper didn’t calculate the width properly so each slide was causing a horizontal scroll by pushing the container. To solve it I also added
grid-template-columns: 100%;
to the.parent
.Another fix I did for this before was to wrap swiper in another grid and that seemed to do the trick. But that has an issue that I will explain bellow.
Scenario 2
Parent element with display grid and multiple columns. Swiper nested 2 levels down in the
.col
element.In this case Chrome is fine, but on Firefox Swiper will grow to infinity without stoping. To fix this I had to change the template columns to
grid-template-columns: repeat(var(--columns, 12), minmax(0, 1fr));
.Initially to solve this issue was to disable the resize observer in settings. Seems that the observer triggers all the time.
Works for me like this:
Have there been any other fixes? This thread was created on Swiper 4.2.2, but I’m getting similar painful behavior with SwiperJS v6.1.2 & CSS Grid.
In some scenarios, Swiper disregards the grid (as if it has been absolutely positioned). In some scenarios, Swiper will not resize responsively (i.e,. always the max-width of the grid child it’s in), even within a breakpoint. Setting overflow:hidden does not fix the issue, and unluckily, we are tied to the fr units. It’s one of grid’s by-design features to automatically calculate the viewport in fractional units.
I wish we could use flexbox in our layout, but the site is quite deeply integrated in grid. I agree with @ckihneman: if CSS grid incompatibilities are present in the stable release, it should be noted somewhere in the documentation. Grid is a first-class citizen of CSS, at least since early 2017.
The only reliable solution I’ve found: very carefully limiting the nesting of any SwiperJS element, even divs with zero CSS set. I can get, at most, exactly grid -> grid child -> swiper element. Anything more destroys the layout.