Dynamic height for material ui tab containers - css

I'm having a problem which at first I thought it was the general configuration of my app and the height I was giving to my page wrapping classes. But I made a simple out of the box material ui tab example and it seems this is natural to material ui Tabs Component.
Material UI tabs component gives their tab container the same height, being that height the largest of all its containers. So if you have one tab content with lots of content in it, it makes the other tab contents just as large, even though they may only have one text field and a button in them.
How can I make it that the height of the container adjusts to the content of its own tab?
Here is a visual
Here is why TAB ONE is so large, TAB TWO is setting the height
Here is a webpackBin for you to see the code working and mess with it.
One hack I've done so far is setting a definite height and overflow, but I don't want to do that because it creates a double scroll bar (one in the tab container, one in the body) besides, it's buggy looking.
I would like it if the tab container (the one with the green border) adjusts to the content as it does in TAB TWO, BUT individually.
Thanks in advance!

If you set the height based on the given element's current visibility you will be able to resolve this issue.
Example
.react-swipeable-view-container > div[aria-hidden="false"] {
height: 100%;
}
.react-swipeable-view-container > div[aria-hidden="true"] {
height: 0;
}
Note: this solution could be improved by using a better selector, something more descriptive like a class name. I suppose it's subjective though, using an attribute selector is not technically wrong and actually more specific than just a class.
Demonstration: https://www.webpackbin.com/bins/-Ky0z8h7PsdTYOddK3LG

animateHeight will animate height on tab change. if all tabs have different height it will show height accordingly.
Example:
<SwipeableViews
animateHeight // it will animate height on tab change
>
<div>{'slide 1'}</div>
<div>{'slide 2'}</div>
<div>{'slide 3'}</div>
</SwipeableViews>
Happy Coding ...!

There's a merge request that have been accepted here on the lib that could be interesting with a new method called updateHeight https://github.com/oliviertassinari/react-swipeable-views/pull/359
<SwipeableViews
action={actions => {
this.swipeableActions = actions;
}}
animateHeight
>
<div>{'slide n°1'}</div>
<div>{'slide n°2'}</div>
<div>{'slide n°3'}</div>
</SwipeableViews>
Then:
componentDidUpdate() {
this.swipeableActions.updateHeight();
}

Related

How to get rid of useless scrollbars in a material dialog when a radio-group is used?

This Stackblitz example opens a simple dialog which contains a radio group in the mat-dialog-content div.
You can see that the dialog-content shows an ugly scrollbar:
This does not happen when other components are used: e.g. input, etc.
Using chrome dev-tools, I can see that the mat-radio-buttons have a height of 20px:
but the mat-radio-group only has a height of 17px:
Is this a bug in angular material components (the example uses version 12.0.4), or is there a simple workaround/css that we can use to get rid of the scrollbar?
I've tried explicitly setting the height on the mat-radio-group, but this has no effect.
Notes:
in production we do of course have many dialogs and some of them are large and need the scrollbars
we need an application wide solution/workaround
simply hiding the scrollbars is not okay: it must remain auto so that the dialog can react to size changes (e.g. user rotates device, some items are shown/hidden dynamically, etc.
For now we came up with a workaround that fixes the issue in all our 30+ dialogs.
The nice thing is that we can apply it in one place, in styles.scss:
.mat-dialog-content {
padding-bottom: 10px !important;
}
We just add a padding to the bottom of the dialog content area and then scrollbars: auto works as expected in all our dialogs (small and large). i.e. when you make the browser window larger/smaller, the scrollbar is automatically shown/hidden.
And it also works when there are multiple mat-radio-groups in one dialog.
The additional padding between the content and bottom dialog-actions is acceptable for our ui.
Stackblitz example with workaround
The reason this happens is due to the ripple effect on the radio button - which takes up additional space and causes the scrollbar to show. See https://github.com/angular/components/issues/20344
There are a number of ways to resolve this, such as using padding or margins on the components or on the dialog content itself like you did. The important thing is that there is enough space added to accommodate the ripple.

Antd Treenode title and height css setting

I am using Antd v4.2.4 Tree (example: virtual scroll) from the link. I woulld like to use the virtual Scroll which can be used by setting "height" prop of the Tree. All is fine till here as in the example.
I would like to apply some css to the scrollbar like both overflowX and Y should be enabled on hover in the container
I would like have the Tree node show in only single line when the title is really big and not wrap it, if I use overflowX css, it doesn't work.
codesandbox
Update1: I see when we set "height" prop to Tree a lot of Divs have the inline css elements so not sure how to override them.
May be there is something small here but I am unable to figure out
I want to have such a look for my TreeNode and when hovered on this container the scrollbar X and Y is visible to see the longer node title please advice
update 2
if the set following css I am able to get the title in single line, but the scroll-X behaves strange. i.e. the scoll-x gets hidden when the Tree height/contents are big and when ypu collapse all treenodes, it shows up
.ant-tree .ant-tree-treenode {
white-space: nowrap;
}
codesandbox
TIA

Polymer paper-dropdown-menu expansion height limited by core-collapse?

I have run into an issue with the paper-dropdown-menu component, where it's expansion height seems to be limited by an enclosing core-collapse on its containing element. Is there a way to prevent this from occurring? (see images demonstrating symptoms below) Another related side effect seems to be that when the number of items in the dropdown creates a dropdown height that would normally expand below the bottom of the containing collapsible element, it causes the CSS top styling of the dropdown to be overridden, nudging the top of the element higher within the collapsible container element itself while it is expanded. Irregardless of its new top alignment, it still doesn't show the entire list of options as the height of the dropdown itself remains the same. Has anyone run into similar issues? I can post a jsbin, but its a bit convoluted due to me using a custom polymer element that consists of the icon, input control, and an optionally displayed/selectable unit of measure. So before doing that I was hoping someone might recognize this issue right away and be able to point me in the right direction. This is using chrome v38 and the latest paper-dropdown-menu and core-collapse components (bower ^0.4.0)
Unexpanded (note the top alignment):
Expanded (there should be 5 options, but they are being cut off by core-collapse and note the altered top alignment as well):
Proper operation (when dropdown height is same or less than containing collapsible element height):
In core-collapse there is new property 'allowOverflow' to allow collapsible element to overflow when it's opened. This should help paper-dropdown-menu to expand inside core-collapse. The new property is only in core-collapse#master branch and will be available in the next release.
<core-collapse allowOverflow>
<div class="content">
<paper-dropdown-menu>
...
</paper-dropdown-menu>
</div>
</core-collapse>
The new 'layered' attribute of the latest version of paper-dropdown resolves this issue.

How do I get any number of links to space evenly?

Alright, so here is the situation...
Say I have a navbar for a site, and I allow users to change the number of links they want on this navbar. This means they could have 3, 5, 10, etc.
What I want to do is make it so that if one link is up, it only takes up, say, 1/5th of the space on the navbar. If I weren't using borders, I might do something like:
width: 18%;
padding: 0 1%;
However, I have two problems with this:
1) For 4 buttons, that's fine that it doesn't fill up the whole row. It would look ugly if the links were too wide... but when I have 6 or 7 buttons, it's got huge overflow!
2) Since I have borders, I can't use a percentage value for the borders or the widths, because I can't properly estimate how much of the percentage it will be.
Now, I know I don't have to use percentage values, but what I would ideally prefer is that the first button is the smallest possible size necessary for all the other buttons to fit properly, meaning that if I have 950px and 6 links, the first link can be about 150px while the others are 160px... that's fine. I want all the other buttons on the navbar to be equally sized, regardless of how many links there are.
I also need for it to accept a border... I figure the way to do this is to put a border in the nested div, so that way it doesn't effect the overall width of the button? This is all well and good, but I'm still plagued by the issue of not being able to design a dynamic site using the style I want if I can't get all the nav buttons to fit the width properly.
Are there some js tricks I could use? I don't even know...
Thanks
Edit: Here is my demo fiddle
A pure CSS solution, based on justification of the links, though still as semantic list items:
See demo fiddle.
Tested on W7 in IE7, IE8, IE9, Chrome 12, SafariWin 5, Opera 11, FF 4.
Update:
Concerning the width: Since you dynamically inject the navigation links into the HTML page, it likely is also possible to classify the navigation bar style.
See updated fiddle.
Here's a solution with jQuery
http://jsfiddle.net/pxfunc/kKJcr/
The menu is dynamically sized based on number of menu items and the width of the nav ul
var $nav = $('#nav');
var formatNav = function() {
var menuItemCount = $nav.children().length,
// base width
menuItemWidth = $nav.children().width(),
// border + padding + margin + base width of the menu item
menuItemOuterWidth = $nav.children().outerWidth(true),
// border + padding + margin only for the menuItem
menuItemDiff = menuItemOuterWidth - menuItemWidth,
// menu item container width (the <ul>)
navWidth = $nav.width();
$nav.children().width(Math.round(navWidth / menuItemCount) - menuItemDiff);
};
I did something like this at a previous job, but it did require a blend of JS and CSS.
One way to do it with JS - you need to simply take the total width of the navbar (minus padding, borders, etc, of course) and divide the number of buttons shown - then dump that out as the css width:width/numbOfbuttons%; on each button.
Just be careful not to hit exactly 100% cause this may cause wrap.
However - ideally (and the way we did it) this is much easier if you have a known number of potential buttons, or combinations.
Then, the solution is to set up a series of css classes designed to each scenario:
.oneButt a{width:widthThatLooksNotStupid%;}
.twoButt a{width:49%;}
/* etc */
And then just have the JS evaluate and set the specially designed class on the parent. Yeah..this requires a bit more CSS writing, and requires that you don't have an infinite number of potentials...
.ninehundredsevetyfiveButt a {width:FFFF;}
.ninehundredsevetysixButt a {width:UUUUU;}
...right. BUT - you get to set up a nice styling that actually fits various scenarios.
UPDATE from my comment below. Use general uh...classes...of situations, and apply these via JS:
.notEnoughToFillSpaceCruizer {width:wide;}
.enoughToFillSpaceCruizer {width:notAsWide;}
.jekPorkins {color:fuschia; font-size:99em; content:"You've got a problem..."; /* the user has failed, administer punishment*/}
Maybe you should question your design of trying to fit a dynamic number of buttons onto single row. I think the best design for you is a drop down navigator (like a window menu). That way it doesn't matter how many nav options the users adds, the design is still useable.
If you simply must have a nav bar with no drop downs, the short answer is to use a <table> if you need to support older browsers. At least a table will not wrap, but at some point the design of your site will look awful if it's squashed too much.
I'm sure there could CSS3 answers but I dont know them.

Horizontal scrollbar hides content of ApplicationControlBar

I have an application control bar at the bottom of my Flex application (with attributes width="100%", dock="false", left="0", bottom="0", height="50"). It contains a lot of elements (like buttons and labels). The width of the SWF is the width of the browser.
When the user makes the width of the browser window smaller, after a certain point, the components on the application control bar gets "squished": they are forced on top of each other. And so, it becomes confusing and ugly. To ensure that that doesn't happen, I've set the minWidth attribute to a value so that it'll always display the components without them overlapping each other.
But then, a horizontal scrollbar appears and hides the bottom half of the application control bar.
I've googled and I found this article: flex verticalscrollpolicy bug (referenced by this SO question: Flex: Prevent scrollbar from covering content when automatically displayed).
But that seems to apply only to a fixed size component. My component's width is a percentage. Any ideas on how to have the horizontal scrollbar appear and have it not cover up the application control bar?
Thanks!
See if adding the following code to the overriden validateSize method (as in the scrollpolicy bug page you linked to) solves the problem.
if (width < measuredWidth)
{
height = normal-height + height-of-the-horizontal-scrollbar;
}
else
height = normal-height;
(Find the normal height of the application control bar and the scroll bar (trace them out) and use those values).
So this happens when the ApplicationControlBar is fixed at the bottom: bottom=0 and left=0. The easiest solution is to make the bar a lot taller (that'll push the content way higher than the scrollbar height). But that makes it kinda ugly.
So another solution: in the MXML file, I capture the Resize event. And in that function, I do this:
if (width < bar.minWidth) // width is the width of the SWF
{
bar.height = ORIGINAL_SIZE + 10;
hbox.setStyle("verticalAlign", "top");
hbox.setStyle("verticalCenter", -10);
} else {
// normal case
box.height = ORIGINAL_SIZE;
hbox.setStyle("verticalAlign", "middle");
hbox.setStyle("verticalCenter", 0);
}
And the horizontal scrollbar doesn't hide the content anymore! Also, the Resize event doesn't get triggered when the bar has a minWidth & the width of the stage is less than that.
I had this come up today and I slightly tweaked sri's if statement like this:
if (buttonContainer.horizontalScrollbar)
{
// Change height & style properties
}
else
{
// Return to original properties.
}

Resources