Materialize: Swipeable tabs showing half-page width

Created on 27 Jan 2017  路  20Comments  路  Source: Dogfalo/materialize

Description

On my website I had some tabs in header. I just added {swipeable:true} to the tab init function, but now the tab divs are displayed not in full width.

bug

Most helpful comment

@DanielRuf Sorry for forgetting the row markup, I feel it misleaded the actual issue.

Issue

The original issue was unfortunately not fixed. I guess it's what @Badlapje is trying to say too.

The problem concerns the height of the inner carousel. It doesn't fit the size of the content, it's not vertically responsive, it's fixed to 200px.

Demo

Investigation

Further investigation shows that .carourel-item uses position: absolute;. However, a parent cannot inherit its height from a child _absolutely_ positioned.

That's why Materialize sets the .carousel height during JS initialization. and fails in most cases because of the 200px.

@triskill idea was to reset the carousel height based on its context but it still have some flaws.

From my point of view, it's a design problem which leads to a dead in.

position: absolute; => fixed height => not vertically responsive => find the _tallest_ item at js init => broken if the content changes after init => init again and so on...

Solution

image

@DanielRuf Thank you for your time. Long live Materialize 馃帀

All 20 comments

I found this in materialize.css to be causing the problem:
.carousel .carousel-item { display: none; width: 200px; height: 200px; position: absolute; top: 0; left: 0; }

I just changed that width value you suggested to "100%" and it's now working. Haven't figured out how to correct the height value, though

Exactly the same problem here.
Tried it also ,the height is the problem now.

I managed to do like that:
.tabs-content.carousel { height: 100%; overflow-x:hidden; overflow-y: scroll; } .tabs-content.carousel .carousel-item { width: 100%; height: 100%; } html,body{ overflow:hidden; height:100%; }

my solution for swipeable tabs in modal (jQuery):

$('.modal').modal({
    ready : function(modal, trigger){
        // initialize tabs
        $('ul.tabs').tabs({
            swipeable : true
        });
        // remove materialize default 200px and 400px carousel height
        var modalH = pixelsToNumber($(modal).css('height'));
        var swipeH = pixelsToNumber($(modal).find('.tabs').css('height'));
        var footerH = pixelsToNumber($(modal).find('.modal-footer').css('height'));
        var carouselHeight = modalH -swipeH -footerH;
        $('.modal .carousel').css('height', carouselHeight+'px');
        $('.modal .carousel').css('overflow-y', 'auto');
    }
});
var pixelsToNumber = function(pixels){
    return Number(pixels.substring(0,pixels.length-2));
};

Demo

Bug

image

Expected behavior

image

@donacross use the right markup and do not forget the wrappers https://codepen.io/anon/pen/KqapbE?editors=1000

http://materializecss.com/tabs.html#structure

that codepen shows the exact same problem as described by @donacross ... how is that a fix?

if one replaces the content of the offical docs with something that has a big height it also get's truncated btw

that codepen shows the exact same problem as described by @donacross ... how is that a fix?

What exactly do you mean? He used the wrong markup. The codepen that I gave shows the expected behavior.

in your codepen: paste 4 times the current text into the div for the tab. You'll notice the height is limited and no scrollbar appears. Try the same with the official demo and you'll see the same problem again. If the text is too long, it is hidden with no scrolling possible.

One could use a height with xxx px, but if the content of the different tabs differs, than that is not an option, as it is for me on the site i'm currently trying to develop. check this: http://test.listoire.be/discipline/2

It seems my css skills are lacking, because i cannot trace the root of the issue. I've tried adding clearfix classes, setting pretty much everything to height 100%, adding overflow hidden to several elements, nothing works. The only thing that does work is using absolute px values for the height, but that is not an option.

added overflow-y: auto which at least gave me a scrollbar. But it looks far too ugly and doesn't resolve the height issue, just a dirty hack atm.

@DanielRuf Sorry for forgetting the row markup, I feel it misleaded the actual issue.

Issue

The original issue was unfortunately not fixed. I guess it's what @Badlapje is trying to say too.

The problem concerns the height of the inner carousel. It doesn't fit the size of the content, it's not vertically responsive, it's fixed to 200px.

Demo

Investigation

Further investigation shows that .carourel-item uses position: absolute;. However, a parent cannot inherit its height from a child _absolutely_ positioned.

That's why Materialize sets the .carousel height during JS initialization. and fails in most cases because of the 200px.

@triskill idea was to reset the carousel height based on its context but it still have some flaws.

From my point of view, it's a design problem which leads to a dead in.

position: absolute; => fixed height => not vertically responsive => find the _tallest_ item at js init => broken if the content changes after init => init again and so on...

Solution

image

@DanielRuf Thank you for your time. Long live Materialize 馃帀

@donacross thx for pointing out absolute positioning has height implications for the parent. I did not know this.

Flexbox might be indeed a great solution in the near future and make such calculations / estimations in components obsolete.

great solution in the near future

@DanielRuf Does legacy browser support prevents Materialize to move forward ? Flexbox support seems good enough.

What should we do meanwhile ?

IE is still a bit problematic. We could use flexbox for this component but keep a fallback for IE and other browsers.

For Full Width
Use col s12 class

For Auto Height Instead of 200px
.tabs-content .carousel-item { height: auto; }

@atemiz that is definitely a much cleaner solution. Maybe we could add some classes for this.

I stumbled across this issue as well and I figured I would leave my workaround here.

The Problem: Having tabs with images will cause the tabs-content to be resized to the size of the image.
Explanation of Problem: _setCarouselHeight is called in the constructor and in _handleResize when fullWidth = true (it will be true because the carousel instance is initialized with fullWidth: true in the tabs component ), _setCarouselHeight searches for an img element in the first .carousel-item and sets the height of the carousel to that of the found img.
Workaround: Implement your own _setCarouselHeight.
Example:

$('#img-0').one('load', () => $('.tabs-content').css('height', $('.carousel-item .row').css('height')))
tc._setCarouselHeight = function() {
    $('.tabs-content').css('height', $('.carousel-item .row').css('height'))
    this._autoScroll()
}

Example Notes:

  • I am setting the initial height on the first line (the img wasn't probably loaded when the carousel initialized)
  • I am calling ._autoScroll because it should be called in _handleResize but it's not for whatever reason, instead ._scroll is called with no arguments !?
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ruslandzhumaev picture ruslandzhumaev  路  3Comments

locomain picture locomain  路  3Comments

lpgeiger picture lpgeiger  路  3Comments

alexknipfer picture alexknipfer  路  3Comments

ericlormul picture ericlormul  路  3Comments