How to control the width of Material-UI vertical tabs? - css

I am working with Material-UI tabs. Thanks for the help of others in the threat at Creating a Material-UI tab with image tabs instead of text labels, I was able to get images working for my tabs but I cannot control the width of the tabs no matter how small I make the images - the tabs do grow in width if I make the images larger.
I have a Code SandBox at https://codesandbox.io/s/lucid-stonebraker-q1r4v?file=/src/App.js that demonstrates the problem.
I did manage to set the width of the tabs using inline styles but it just clipped the content to the right rather than centering the image in the narrower tab.
Without the inline style, there is a responsive breakpoint at about 600 pixels. Below the breakpoint, the tab width is about 72 pixels. Larger than the breakpoint, the tab width is about 160. I just guessed these numbers by measuring a different browser window and overlying this app on it. If I do manually force the width with the inline style, I can see that the image location still moves at the breakpoint as though the underlying width that the images are centering to is the original tab width as though I hadn't forced the width.
I settled on these exact numbers of width because the visual measurement matched very close to two min-width numbers in the Material-UI tab.js source code. It could be coincidence. I actually did try changing those in the source code and testing again but they had no effect on the breakpoint behavior so I put the file back to original.
If it's at all possible, I'd like to be able to set the width to my own needs, set margins/padding to my own needs, and still have the images centered in the result.

Ciao, to center the image on Tab you have to pass a style to flexContainerVertical class on Tabs in this way:
<Tabs
orientation="vertical"
value={value}
onChange={handleChange}
aria-label="Vertical tabs example"
className={classes.tabs}
classes={{
flexContainerVertical: classes.flexContainerVertical // pass the class flexContainerVertical
}}
>
Then on your makeStyles:
const useStyles = makeStyles((theme) => ({
...
flexContainerVertical: {
display: "flex",
alignItems: "center",
}
}));
And Tab images will appear on center of the Tab.
Here your codesandbox modified.

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.

Show image in Square grid (React + Material UI Grid)

I use React + [Material UI Grid][1] to show my images, the images are in different sizes, and I want to:
Keep image ratio
Make image fit the parent container square(in other words, all images in a row with the same height)
The problem is that, The number of columns in Grid is variant, sometimes 3 columns(on mobile) and sometime 6 columns(on PC), React calcuate the width of image Dynamically. I don't know the run-time image width, so i can not set the image height in my css style excatly. any idea? thanks.
You can see the following effect currently, a very tall image makes the grid streched vertically, very ugly.
Use this code. It centres the image inside the Grid and doesn't let it overflow while also not giving the dim in pixels. Although the dimension is fixed to square(a x a) but can be changed.
I had the same issue in the past so I am sharing my own code.
Hope this will be useful as I have used CardMedia with component type img. You can select the relevant CSS if not complete from inspecting.

can you make material ui tab responsive?

Is it possible to make the material ui tab react component responsive?
Documentation of MATERIAL UI TAB
Say I have multiple tab items with a search bar like below
I want to make the input component stretch the whole width of the screen for mobile view (screen less than 500px)
I tried putting width: 100% on the tab with media queries but it didnt work.
I also wanted to remove the focus effect when i click on the search component which is illustrated below
To summarise
1 ) I want the input component to stretch the whole width on smaller screens
2 ) I want to remove the focus effect when clicking the first tab(search component)
This is a working example, forked from your codesandbox: https://codesandbox.io/s/material-demo-fpfw5?file=/demo.js.
Basically I changed something for only screen sizes smaller than 600px:
First, set "max-width" and "width" for first tab to "100%".
Second, set width for input inside tab1 to "100%.
Last, add disableRipple attribute to first tab.
One thing, I use the default breakpoints of Material-UI, which defined here: https://material-ui.com/customization/breakpoints/
If you wanna change to 500px, just define your own breakpoint.

Do not make the width of the button proportionnel to the width of the popup window

I want to make a button in a popup window as Script Lab as follows. Note that, in Script Lab, the width of the button is enough to hold the sentence in one line, even though the popup window is not very wide:
I almost use the same code as ScriptLab:
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
... ...
return (
<div style={{ height: '100vh', display: 'flex', flexDirection: 'column'}}>
<PrimaryButton
style={{ margin: 'auto' }}
text="Open link in new window"
// tslint:disable-next-line: jsx-no-lambda
onClick={() => {
window.open(this.props.url);
}}
/>
</div>
);
Here is my result, where the width of the button is proportionnel to the width of the popup window. As a consequence, the sentence needs to be displayed in 2 rows, which is not what I want.
Does anyone know how to amend the code to get the effect like Script Lab?
Edit 1:
I have made a sandbox: https://codesandbox.io/s/relaxed-feather-i6jz6?file=/src/App.js
Now, the problem is, if we Open In New Window and open https://i6jz6.csb.app/ in a new browser tab several times, we may see a little adjustment of the font of the text in the button. Does anyone know how to avoid that?
On button width:
In order to not have the width of the button grow proportionately with the container you can enforce the width: auto on the button. This way it will only be as wide as it needs to be to contain the text. Value auto is also better than having a fixed width, because it can automatically wrap the text if the popup becomes too narrow to display the text in one line (with fixed width your button would overflow instead - which looks really bad).
On font adjustments
For the font adjustments you experience - this is a very common thing on web and it even has its own name - FOUT (Flash of Unstyled Text). It happens when you use custom fonts on the page, because these are files like any other and so they take some time to download. Browsers prefer displaying the content as early as possible (even without custom fonts loaded) to displaying the perfect content (by waiting on all resources) with some speed penalty.
The only way (at least that I know) to completely avoid FOUT is to use system fonts instead of custom fonts (github does that for example).
If that's not an option, you can minimize the FOUT by caching the fonts on client machines for long times. This way they will experience the flash briefly on the first visit, but not on subsequent ones.
You can also try to minimize the FOUT by telling the browser to try to preload the font files that will be needed for the page (part of the reason why FOUT happens is that browser discovers the fonts very late) https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
Set a fixed width to the button.Setting a fixed width will make it unproportional to the width of the pop-up window.
width:280px;
Second Option: If you use min-width, the button width will decrease to a point.
Third Option: If you use max-width, the button width will increase upto a point.
Fourth Option: You can also use '#media' queries to customize the width according to size of the screen.
You don't want the button's text to wrap, so you'll need to change the font size, which you can do when you find that the button's height increases when the text wraps. I suggest that you create a invisible, but not 'display: none', possibly 'off-screen' version of the button so that the real button's font is changed after you know the right size is needed. Alternatively, what about an image or glyph instead of text, and a Title for the button text?

Setting the avatar in Material UI to actual size by styling child elements to full size of parent

General Question
How is the width and height for the elements inside Material-UI <Avatar/> set?
Specific example
Specifically the challenge I am having is that <AccountCircle/> example: account circle is not filling up the parent.
I am trying to get an avatar of 80x80 but because material-ui adds so many random classes with random margins and padding, I end up with something else. The actual code generated produces an <svg> with a <path> inside which measures approximately 66.67px
const avatarImageStyle = {
width: 80,
height: 80,
};
JSX
<AccountCircle style={Object.assign({}, avatarImageStyle, {color: 'grey' })} />
I faced the same issue on an application I am currently working on. I resolved it by increasing the fontSize of Avatar and then setting the icon to use its parent's font size.
We do not have to specify the width and height of the icon because Material-UI icons (and presumably, icons in general) are symmetric in shape. However, we do have to specify the dimensions of the Avatar, otherwise it will remain the same size as before while the size of the icon inside it will grow large (and the icon will be cropped). Since I use fontSize to increase the size of the contents of the Avatar, using auto for its dimensions will work.
So, for the style of the Avatar, use:
{
fontSize: '80px',
width: 'auto',
height: 'auto',
...
}
and to add your icon, use:
<AccountCircle style={Object.assign({color: 'grey' })} fontSize='inherit' />

Resources