index.js
import React from \'react\'
import TextField from \'@material-ui/core/TextField\'
import style from \'./style\'
import withStyles
You can try out adding the size="small" which is mentioned in the Textfield API
<TextField variant="outlined" size="small" / >
With material-ui v4+, you have to adjust the input padding and the label position to get what you whant.
<TextField label="Label" variant="outlined" />
Suppose we want the above TextField to be 48px height (it's default size is 56px), we just have to do (56px - 48px) / 2 = 4px and in our css file:
.MuiTextField-root input {
/* 14.5px = 18.5px - 4px (note: 18.5px is the input's default padding top and bottom) */
padding-top: 14.5px;
padding-bottom: 14.5px;
}
.MuiTextField-root label {
top: -4px;
}
.MuiTextField-root label[data-shrink='true'] {
top: 0;
}
For styled-components users, all the above block of code can be defined as Sass mixins that can be re-used throughout the code base
import { css } from 'styled-components'
const muiTextFieldHeight = (height: number) => {
const offset = (56 - height) / 2
return css`
input {
padding-top: calc(18.5px - ${offset}px);
padding-bottom: calc(18.5px - ${offset}px);
}
label {
top: -${offset}px;
}
label[data-shrink='true'] {
top: 0;
}
`
}
Then somewhere in your stylesheet
.MuiTextField-root {
${muiTextFieldHeight(40)} /* set TextField height to 40px */
}
The other answer is useful but didn't work for me because if a label
is used in an outlined
component (as it is in the question) it leaves the label
uncentered. If this is your usecase, read on.
The way the <label>
component is styled is somewhat idiosyncratic, using position: absolute
and transform
. I believe it's done this way to make the animation work when you focus the field.
The following worked for me, with the latest material-ui v4 (it should work fine with v3 too).
// height of the TextField
const height = 44
// magic number which must be set appropriately for height
const labelOffset = -6
// get this from your form library, for instance in
// react-final-form it's fieldProps.meta.active
// or provide it yourself - see notes below
const focused = ???
---
<TextField
label="Example"
variant="outlined"
/* styles the wrapper */
style={{ height }}
/* styles the label component */
InputLabelProps={{
style: {
height,
...(!focused && { top: `${labelOffset}px` }),
},
}}
/* styles the input component */
inputProps={{
style: {
height,
padding: '0 14px',
},
}}
/>
Notes
withStyles
HOC, as this approach just seems simpler to mefocused
variable is required for this solution - you get this with final-form
, formik
and probably other form libraries. If you're just using a raw TextField
, or another form library that doesn't support this, you'll have to hook this up yourself.labelOffset
to center the label
which is coupled to the static height
you choose. If you want to edit height
, you'll also have to edit labelOffset
appropriately.fieldset
> legend
) yourself via CSS. For me this wasn't worth it, as I'm fine with using the default font sizes with a height of 44px.The component takes a multiline
prop which is a boolean. Set this to true, and then set the component's rows
prop to a number.
<TextField
multiline={true}
rows={3}
name="Description"
label="Description"
placeholder="Description"
autoComplete="off"
variant="outlined"
value={description}
onChange={e => setDescription(e.target.value)}
/>
To make it narrower, set a height, and add a "dense" margin prop on the TextField to keep the label aligned correctly:
<TextField margin="dense" style={{ height: 38 }} />
You didn't show how you tried to specify the height, but the approach you used for font-size is the right approach. Here's an example showing two text fields with different heights:
import React from "react";
import ReactDOM from "react-dom";
import TextField from "@material-ui/core/TextField";
import { withStyles } from "@material-ui/core/styles";
const styles = {
input1: {
height: 50
},
input2: {
height: 200,
fontSize: "3em"
}
};
function App(props) {
return (
<div className="App">
<TextField
variant="outlined"
InputProps={{ classes: { input: props.classes.input1 } }}
/>
<TextField
variant="outlined"
InputProps={{ classes: { input: props.classes.input2 } }}
/>
</div>
);
}
const StyledApp = withStyles(styles)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(<StyledApp />, rootElement);
And here is a code sandbox with the same code so you can see it running.