困っている問題
今、Reactを使って簡単なWebアプリケーションを作っています。ランディングページの構成はシンプルで上部にヘッダ、画面中央は画像というようになっています。ヘッダにはLOGINとSIGNUPのボタンがありこれを押すと画面中央付近にログインやサインアップのためのフォームが出てくるようになっています。いま困っているのはこのフォームを出したときに何故かヘッダのLOGIN, SIGNUPの配置が影響を受けてしまうことです。
下に初期画面(上)とフォームを出した時(下)の画面のスクリーンショットを載せます。少しわかりにくいかも知れませんが、ログインフォームを出したときにはヘッダのLOGINが右に寄ってSIGNUPとの間隔が狭くなってしまっています。
これはおそらくCSSの問題であろうというところまではわかるのですがどのように解決すればよいのかわかりません。
コードの詳細
アプリケーションの中核のコード(App.js)
javascript
1import React from 'react'; 2import './App.css'; 3import Header from './components/Header'; 4import Footer from './components/Footer'; 5import ToppageMain from './components/ToppageMain'; 6 7function App() { 8 return ( 9 <div className="App"> 10 <Header /> 11 <ToppageMain /> 12 <Footer /> 13 </div> 14 ); 15} 16 17export default App;
全体のデザインは App.css に定義されており、その中身は下のようになっています。
css
1.App { 2 text-align: center; 3 height: 850px; 4} 5 6.App-header { 7 background-color: #282c34; 8 height: 5%; 9 min-height: 5vh; 10 display: flex; 11 flex-direction: column; 12 justify-content: center; 13 font-size: calc(10px + 2vmin); 14 color: white; 15} 16 17.App-link { 18 color: #09d3ac; 19} 20 21nav { 22 display: flex; 23 flex-direction: row; 24 text-align: left; 25 width: 100%; 26} 27 28nav > h1 { 29 font-family: 'Alata', sans-serif; 30 font-size: 36px; 31 margin-top: auto; 32 margin-bottom: auto; 33 margin-left: 20px; 34 margin-right: 100px; 35} 36 37.icon { 38 border-radius: 15px; 39 text-align: center; 40 width: 3%; 41 margin-top: auto; 42 margin-bottom: auto; 43} 44 45li > a { 46 text-decoration: none; 47 color: #fff; 48} 49 50li > a:hover { 51 color: #FEC34C; 52} 53 54.field { 55 width: 100%; 56 height: 100%; 57 background: linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0.3)), url("./images/maarten-van-den-heuvel-8EzNkvLQosk-unsplash.jpg"); 58 background-size: cover; 59} 60 61footer { 62 background-color: #282c34; 63 height: 6.1%; 64 text-align: right; 65 font-size: 14px; 66 color: #fff; 67} 68 69.photographer { 70 text-decoration: none; 71 color: #fff; 72 font-family: 'Alata', sans-serif; 73} 74 75.copyright { 76 text-align: center; 77}
ヘッダは Header.js に定義しており、中身は下のようになっています。
javascript
1import React from 'react'; 2import { Switch, Route, Link } from 'react-router-dom'; 3import { makeStyles } from '@material-ui/core/styles'; 4import TopLinks from './TopLinks'; 5import Inner from './Inner'; 6 7const useStyles = makeStyles(theme => ({ 8 link: { 9 textDecoration: "none", 10 color: "white", 11 }, 12})); 13 14export default function Header() { 15 const classes = useStyles(); 16 return( 17 <div className="App-header"> 18 <nav> 19 <h1><Link to="/" className={classes.link}>Paper list</Link></h1> 20 <Switch> 21 <Route exact path="/" component={TopLinks}/> 22 <Route path="/login" component={TopLinks}/> 23 <Route path="/signup" component={TopLinks}/> 24 <Route path="/main" component={Inner}/> 25 </Switch> 26 </nav> 27 </div> 28 ) 29}
LOGIN, SIGNUPボタンは TopLinks.js に定義しています。
javascript
1import React from 'react'; 2import { Link } from 'react-router-dom'; 3import { makeStyles } from '@material-ui/core/styles'; 4 5const useStyles = makeStyles(theme => ({ 6 list: { 7 display: "table", 8 width: "12%", 9 Float: "right", 10 marginLeft: "auto", 11 padding: "0 25px", 12 }, 13 links: { 14 display: "table-cell", 15 fontSize: 16, 16 fontFamily: "'Alata', sans-serif", 17 textAlign: "right", 18 paddingRight: 5, 19 marginRight: "3%", 20 marginTop: "auto", 21 }, 22})) 23 24export default function TopLinks() { 25 const classes = useStyles(); 26 return ( 27 <ul className={classes.list}> 28 <li className={classes.links}><Link to="/login">LOGIN</Link></li> 29 <li className={classes.links}><Link to="/signup">SIGNUP</Link></li> 30 </ul> 31 ) 32}
ログイン画面は Login.js に定義しています。
javascript
1import React from 'react'; 2import Avatar from '@material-ui/core/Avatar'; 3import Button from '@material-ui/core/Button'; 4import CssBaseline from '@material-ui/core/CssBaseline'; 5import TextField from '@material-ui/core/TextField'; 6import FormControlLabel from '@material-ui/core/FormControlLabel'; 7import Checkbox from '@material-ui/core/Checkbox'; 8import Link from '@material-ui/core/Link'; 9import Grid from '@material-ui/core/Grid'; 10import LockOutlinedIcon from '@material-ui/icons/LockOutlined'; 11import Typography from '@material-ui/core/Typography'; 12import { withStyles } from '@material-ui/core/styles'; 13import Container from '@material-ui/core/Container'; 14 15class Login extends React.Component { 16 constructor(props) { 17 super(props); 18 19 this.state = { 20 email: '', 21 password: '', 22 }; 23 24 this.handleEmail = this.handleEmail.bind(this); 25 this.handlePassword = this.handlePassword.bind(this); 26 } 27 28 handleMainPage = () => { 29 // TODO: Implement it 30 this.props.history.push('/main'); 31 } 32 handleEmail(event) { 33 this.setState({email: event.target.value}); 34 } 35 handlePassword(event) { 36 this.setState({password: event.target.value}); 37 } 38 39 40 render() { 41 const { classes } = this.props; 42 43 return ( 44 <Container 45 component="main" 46 maxWidth="xs" 47 className={classes.outer} 48 > 49 <CssBaseline /> 50 <div className={classes.paper}> 51 <Avatar className={classes.avatar}> 52 <LockOutlinedIcon /> 53 </Avatar> 54 <Typography component="h1" variant="h5"> 55 Login 56 </Typography> 57 <form className={classes.form} noValidate> 58 <TextField 59 variant="outlined" 60 margin="normal" 61 required 62 fullWidth 63 id="email" 64 label="Email Address" 65 name="email" 66 value={this.state.email} 67 onChange={this.handleEmail} 68 autoComplete="email" 69 autoFocus 70 /> 71 <TextField 72 variant="outlined" 73 margin="normal" 74 required 75 fullWidth 76 name="password" 77 value={this.state.password} 78 onChange={this.handlePassword} 79 label="Password" 80 type="password" 81 id="password" 82 autoComplete="current-password" 83 /> 84 <FormControlLabel 85 control={<Checkbox value="remember" color="primary" />} 86 label="Remember me" 87 /> 88 <Button 89 type="submit" 90 fullWidth 91 variant="contained" 92 color="primary" 93 className={classes.submit} 94 onClick={this.handleMainPage} 95 > 96 Sign In 97 </Button> 98 <Grid container className={classes.footer}> 99 <Grid item xs> 100 <Link href="#" variant="body2"> 101 Forgot password? 102 </Link> 103 </Grid> 104 <Grid item> 105 <Link href="/signup" variant="body2"> 106 {"Don't have an account? Sign Up"} 107 </Link> 108 </Grid> 109 </Grid> 110 </form> 111 </div> 112 </Container> 113 ) 114 } 115} 116 117const useStyles = theme => ({ 118 '@global': { 119 body: { 120 backgroundColor: theme.palette.common.white, 121 }, 122 }, 123 outer: { 124 display: "table", 125 verticalAlign: "middle", 126 backgroundColor: "rgba(255,255,255,0.9)", 127 borderRadius: 10 128 }, 129 paper: { 130 display: 'flex', 131 flexDirection: 'column', 132 alignItems: 'center', 133 }, 134 avatar: { 135 margin: theme.spacing(3), 136 backgroundColor: theme.palette.secondary.main, 137 }, 138 form: { 139 width: '100%', // Fix IE 11 issue. 140 marginTop: theme.spacing(1), 141 }, 142 submit: { 143 margin: theme.spacing(3, 0, 2), 144 }, 145 footer: { 146 marginBottom: theme.spacing(3), 147 }, 148}); 149 150export default withStyles(useStyles)(Login);
よろしくおねがいします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/28 04:43
2019/11/28 04:58
2019/11/28 05:50
2019/11/28 06:29
2019/11/28 07:22
2019/11/28 07:55 編集
2019/11/29 03:48