I'm using the ant.design Card component to display the messages for a chat webapp in react/redux. Right now each card gives too much space around the card. Is there anyway to make the card wrap the text closer?
Where the React code is:
<Card
bordered={false}
style={{
// other styles...
width: width,
height: 70 <== just decreasing this number doesn't work
}}
>
<p>{message.contents}</p>
</Card>
Just decreasing the height doesn't work and produces:
Instead of using Cards I just used a regular p tag with borderRadius and padding:
<p
style={{
borderRadius: '25px',
padding: '4px 15px 4px'
}}
>
You can use the inline style property bodyStyle to apply styles to the card content.
The better way to keep your components clean use css.
<Card className="custom-card" bordered={false}>
<p>Hey Hunter</p>
</Card>
css:
.custom-card {
width: 100px;
height: 35px;
}
.custom-card > .ant-card-body {
display: table;
width: 100%;
height: 100%;
padding: 5px;
}
.custom-card > .ant-card-body > p {
text-align:center;
vertical-align: middle;
display: table-cell;
}
Check the DEMO.
I would inspect the element in the dev tools first, but more than likely, you should set the height of the card to 'auto' and add padding to the text inside. Putting a class on the p tag:
<p class='message-contents'>{message.contents}</p>
and targeting it:
.message-contents {
padding: 20px;
}
will set the space inside of the card to 20px on each side of the text. Change this to what you want.
Also I suggest using a class on the card also and putting all styling in an external stylesheet, but either works.
You can use the gutter property of Row as grid spacing, we recommend set it to (16 + 8n) px. (n stands for natural number.)
You can set it to a object like { xs: 8, sm: 16, md: 24, lg: 32 } for responsive design.
You can use a array to set vertical spacing, [horizontal, vertical] [16, { xs: 8, sm: 16, md: 24, lg: 32 }].
https://ant.design/components/grid/
Related
I have a Material UI <Paper> component that serves as a background and exists in my main React component- it's nested inside a <ThemeProvider>, which is nested a <div>, which is then nested in the <body>. I've applied the viewport: 100vh attribute to make it take the full height of the screen. It does take up the full height, but only prior to rendering another <Paper> component on the right hand side. Then the bottom of the paper no longer extends to the bottom of the screen:
Beginning of App render method:
return (
<ThemeProvider theme={theme}>
<Paper style={{ height: '100vh', boxShadow: 'none' }}>
<Container fluid id='app'>
.......
)
I tried applying the viewport: 100vh attribute to both the <div> that encloses the App component in index.js and the <body> element in index.html. There wasn't any difference. It may be worth mentioning that I'm using react-bootstrap Containers/Rows/Cols for my grid system at the moment (haven't switched that part to Material UI yet), but they're all nested inside the Paper, so I wouldn't expect they would be causing the problem. I also tried removing any css applied to the <Container> but it didn't help.
I'm also using a muiTheme for the <ThemeProvider> (obviously):
export default function createTheme(isDarkModeEnabled) {
return createMuiTheme({
palette: {
type: isDarkModeEnabled ? 'dark' : 'light',
primary: {
main: '#6DD3CE',
dark: '#639FAB'
},
secondary: {
main: '#52CBC5'
}
},
typography: {
fontFamily: [ 'montserratlight', 'Times New Roman' ].join(','),
body2: {
fontFamily: [ 'montserratmedium', 'Times New Roman' ].join(',')
},
h3: {
fontSize: '1.75rem'
},
button: {
fontFamily: [ 'montserratmedium', 'Times New Roman' ].join(',')
}
}
})
}
Update and Solution
I did redo my layout using flexbox instead of react-bootstrap, and ultimately fixed the problem by using min-height: 100vh instead of height: 100vh for my container so it had room to expand.
It appears that your <Container> has a bit of padding that is causing the content to go beyond its height:
This could also be due to your <textarea /> not having an assigned height. This is a particular issue when you are in a medium-sized screen.
If you are already planning to do away with Bootstrap's layout system, consider flex box and styled containers:
import React from "react";
import styled from "styled-components";
export default function App() {
return (
<Container>
<StyledHeader>Hello StackOverflow</StyledHeader>
<StyledCol>
<p>This is column 1.</p>
</StyledCol>
<StyledCol>
<p>This is another column.</p>
</StyledCol>
</Container>
);
}
const Container = styled.div`
height: 700px;
width: 100%;
display: flex;
flex-flow: row wrap;
justify-content: space-between;
`;
const StyledHeader = styled.h1`
height: 30%;
width: 100%;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
`;
const StyledCol = styled.div`
height: 70%;
width: 50%;
& p {
text-align: center;
}
`;
CodeSandbox Example: https://codesandbox.io/s/stack-63802170-flexbox-example-909ol
This will ultimately give you more control over the layout of the page.
I am using material ui Grid for responsive ui.
<Grid spacing={2} xs={12} container={true}>
<Grid item={true} lg={4} md={6} sm={12}>...</Grid>
<Grid item={true} lg={4} md={6} sm={12}>...</Grid>
<Grid item={true} lg={4} md={6} sm={12}>...</Grid>
</Grid>
I want to customize the screen width for breakpoint md to npx and I want to do it only in this one instance. Not throught the app.
I found how to do it for the entire app and also for a single grid instance using styles.
const styles = theme => ({
root: {
[theme.breakpoints.up('md')]: {
width: npx,
},
},
});
But would prefer doing it using css instead of material ui styles. How can I do that?
First, add your-class to the each item. Then use this css:
#media (min-width:960px) { //change min-width to your selected value
.MuiGrid-grid-md-6.your-class {
flex-grow: 0;
max-width: 50%;
flex-basis: 50%;
}
}
That works if your new breakpoint is < 960px. If the value is > 960px, you also need this:
#media (min-width:600px) and (max-width:959px) { //change max-width to (your selected value - 1)
.MuiGrid-grid-sm-12.your-class {
flex-grow: 0;
max-width: 100%;
flex-basis: 100%;
}
}
You can use the same reasoning for other breakpoints as well. E.g: For lg, which the default breakpoint is 1280px:
#media (min-width:1280px) {//change min-width to your selected value
.MuiGrid-grid-lg-4.your-class {
flex-grow: 0;
max-width: 33.333333%;
flex-basis: 33.333333%;
}
}
// If breakpoint > 1280px, also add
#media (min-width:960px) and (max-width:1279px) { //change max-width to (your selected value - 1)
.MuiGrid-grid-md-6.your-class {
flex-grow: 0;
max-width: 50%;
flex-basis: 50%;
}
}
Further customisation would depend on which values you set, i.e. lg={4} vs lg={3}... I've pasted the full css definitions for MuiGrid here.
I am rendering a simple view. It consists of an image on the right and some text on the left. This is how it looks like:
return (
<View style={styles.companyContainerStyle}>
<View>
<Text>{this.props.companyNameAr}</Text>
<Text>{this.props.descriptionAr}</Text>
</View>
<View style={styles.imageContainerStyle}>
<Image
style={styles.imageStyle}
source={{ uri: this.props.logo }}
resizeMode='contain'
resizeMethod='auto'
/>
</View>
</View>
);
The following is the styles I applied to make the text and image aligned next to each other:
const styles = {
companyContainerStyle: {
flex: 1,
flexDirection: 'row',
padding: 10
},
imageContainerStyle: {
borderRadius: 5,
borderWidth: 2,
borderColor: '#2279b4',
padding: 1,
},
imageStyle: {
flex: 1,
height: 100,
width: 100,
}
}
The very weird part is that it looks like this on the emulator:
I think the length of the text is pushing the image to the very right out of the screen. I thought that the number of lines would adjust accordingly to fit everything in the screen. However its not the case. How do I make everything look neat given that the length of the text is unknown (it is being rendered from a database)??
#container {
display: flex;
justify-content: space-around;
width: 70%;
height: 400px;;
border: 2px solid grey;
padding: 5px;
}
#top_content {
display: flex;
justify-content: space-around;
align-items: flex-start;
}
#para {
width: 60%;
text-align: justify;
margin: 0px;
}
img {
height: 20%;
width: 20%;
}
<div id="container">
<div id="top_content">
<p id="para">adfasdfadf sadfdaafafdasdfadfadfadfdfad dasadfadfadfadfadgvfa sasadasdaf asdfdfdadfadf</p>
<img src="http://lorempixel.com/400/200" alt="myimg">
</div>
</div>
Something like this can make sure that your text will not push your img outside
Add flex: 1 to imageContainerStyle and also add flex: 1 to View that is container of the two Text components.
Reason for this is that if the Text component does not have container with flex: 1 on it the text will try to take all possible space. The container will restrict that
I'm trying to apply some reasonably simple styles to my <Dialog> component. In this case, I am trying to round the corners with a border radius. Here are some simple inline styles that I'd like to use to override the default <Dialog> styles:
let overrideStyles = {
padding: 0,
margin: 0,
borderRadiusTopLeft: '4px',
borderRadiusTopRight: '4px',
};
<Dialog> provides a wide variety of possibilities for overriding internal styles. These include bodyStyle, contentStyle, style, titleStyle, overlayStyle, and actionsContainerStyle. I decided to try to apply these styles to each one.
<Dialog
bodyStyle={overrideStyles}
contentStyle={overrideStyles}
style={overrideStyles}
titleStyle={overrideStyles}
overlayStyle={overrideStyles}
actionsContainerStyle={overrideStyles}
modal={overrideStyles}
>
<TestPanel/>
</Dialog>
When I render my TestPanel, it ends up looking like this:
Notice the corners, where my border radius has not been applied... I opened up the inspector and noticed the following div:
If I apply the border radius styling to the highlighted div, the dialog will have its corners rounded as expected. Which leads me to my question...
How do I override the styles of Material UI's <Dialog> component to apply rounded corners as my CSS is attempting?
I solved it with paperProps property.
<Dialog PaperProps={{
style: { borderRadius: 2 } }}
> .... </Dialog>
This perfeclty worked for me
You can override styles like below.
const styles = {
root: { }
paper: { borderRadius: 15 }
}
// ...
<Dialog classes={{
root: classes.root,
paper: classes.paper
}}>
</Dialog>
Unfortunately, Material UI isn't supremely style-friendly. In this case, there's no prop you can override to change the border-radius, so we've got to apply our own class:
let headerStyles = {
color: 'white',
textAlign: 'center',
fontSize: 24,
backgroundColor: '#3B8DBC',
padding: 20,
borderTopLeftRadius: 4,
borderTopRightRadius: 4
};
let bodyStyles = {
backgroundColor: 'white',
padding: 10,
height: 200
};
<Dialog className='test'>
<div style={headerStyles}>Testing</div>
<div style={bodyStyles}>5:43pm</div>
</Dialog>
Then style that class, and, yes, the border-radius has to be set on both of the below CSS classes as well as the TestPanel header:
/* Some rules use !important because Material UI sets them by default */
.test > div > div {
background-color: #3B8DBC; /* Same background-color as TestPanel */
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.test > div > div > div {
/* Not overriding the color and border radius here too result in your changes
not being visible. */
background-color: inherit !important;
border-top-left-radius: 4px !important;
border-top-right-radius: 4px !important;
}
.test > div > div > div > div {
/* This div is the topmost padding between the modal content and the edge
of the modal */
padding: 0 !important;
}
This ends up looking like what you want:
screenshot here
Hope this helps!
You can override <Dialog /> styles globally in your application when creating your theme object. The paper key of MuiDialog will let you target the border-radius.
const theme = createMuiTheme({
overrides: {
MuiDialog: {
paper: {
borderTopLeftRadius: '4px',
borderTopRightRadius: '4px'
}
}
}
})
Dialog - CSS api
Material UI Theming
The first answer is not working for me. I tried this and it work perfect for me:
sx={{
"& .MuiDialog-container": {
"& .MuiPaper-root": {
width: "100%",
maxWidth: "740px",
borderRadius: "8px"
}
},
}}
I have two pieces of text. I need the first piece to be centered horizontally and vertically, and the second to just be right next to it. Currently the code looks like this:
<View style={styles.runningTimeWrapper}>
<Text style={styles.loggedTime}>00:00</Text>
<Text style={[styles.loggedTime, styles.loggedSeconds]}>00</Text>
</View>
How can I style it so the 00:00 is centered? Using fixed widths is not an option as I need this to work on any screen size.
Here is how it looks currently:
Styles:
loggedTime: {
color: Variables.PURPLE,
fontSize: 44,
alignSelf: 'center',
},
loggedSeconds: {
fontSize: 22,
alignSelf: 'flex-end',
paddingBottom: 8
},
runningTimeWrapper: {
flexDirection: 'row',
justifyContent: 'center',
flex: 1,
},
The desired effect is to have the column of hh:mm aligned with the center of the screen, and the seconds directly next to the minutes.
On all 'center' references, I am talking about horizontal center (x-axis), not vertical(y-axis) (which is set using alignItems /self)
You can set the second span to position:absolute, so it will be out of the normal content flow, and ensure the hour/minute to be centered in the container.
.wrapper {
display: flex;
justify-content: center;
position: relative;
font-family: sans-serif;
}
.hm {
font-size: 44px;
}
.s {
font-size: 22px;
position: absolute;
bottom: 5px;
}
<div class="wrapper">
<span class="hm">12:34</span>
<span class="s">56</span>
</div>
In fact, you don't really need flexbox, the text-align:center is probably enough to do it.
.wrapper {
text-align: center;
position: relative;
font-family: sans-serif;
}
.hm {
font-size: 44px;
}
.s {
font-size: 22px;
position: absolute;
bottom: 5px;
}
<div class="wrapper">
<span class="hm">12:34</span>
<span class="s">56</span>
</div>
You'll need 3 inner wrapper views: an empty one on the left and then wrap the small and big numbers in their own wrapper each. Then give the left and right wrappers flex: 1 to make them the same width.
https://rnplay.org/apps/hLBFng
I'm not 100% certain I understand what you're going for. Are you trying to get the loggedTime to be perfectly centered and the loggedSeconds to be offset to the right of that? Or are you simply trying to get both to be center/center?
I think I was able to get something going here by setting flexDirection: 'row' and adding some paddingTop to the seconds.
Here's a demo on rnplay.org
var styles = StyleSheet.create({
loggedTime: {
color: '#FF5500',
fontSize: 44,
alignSelf: 'center',
},
loggedSeconds: {
fontSize: 22,
paddingTop: 20,
paddingBottom: 8
},
runningTimeWrapper: {
flexDirection: 'row',
justifyContent: 'center',
flex: 1,
},
});