ButtonBaseはMaterial UIに入っているコンポーネントで 画像を並べてCoolにしてくれる物です。 本当に便利なのサイトのトップで使いたいと思います
動きはないですが。全文をみたい人はこちら
material-ui ButtonBase Sample - CodeSandbox
ButtonBaseとは
画像付きのボタンです。ベースの画像があってその上にテキストが表示されている形です。
マウスのカーソルを乗せるとハイライトが入るのです。
CSSでもできるのですが、ちょっとしたコードでかっこいいボタンができるのです。
サンプルソース
import React from 'react'; import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core/styles'; import ButtonBase from '@material-ui/core/ButtonBase'; import Container from '@material-ui/core/Container'; import Typography from './parts/Typography'; //import { Link as RouterLink } from 'react-router-dom'; const styles = (theme) => ({ root: { marginTop: theme.spacing(8), marginBottom: theme.spacing(4), }, images: { marginTop: theme.spacing(8), display: 'flex', flexWrap: 'wrap', }, imageWrapper: { position: 'relative', display: 'block', padding: 0, borderRadius: 0, height: '40vh', [theme.breakpoints.down('sm')]: { width: '100% !important', height: 100, }, '&:hover': { zIndex: 1, }, '&:hover $imageBackdrop': { opacity: 0.15, }, '&:hover $imageMarked': { opacity: 0, }, '&:hover $imageTitle': { border: '4px solid currentColor', }, }, imageButton: { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', color: theme.palette.common.white, }, imageSrc: { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, backgroundSize: 'cover', backgroundPosition: 'center 40%', }, imageBackdrop: { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, background: theme.palette.common.black, opacity: 0.5, transition: theme.transitions.create('opacity'), }, imageTitle: { position: 'relative', padding: `${theme.spacing(2)}px ${theme.spacing(4)}px 14px`, }, imageMarked: { height: 3, width: 18, background: theme.palette.common.white, position: 'absolute', bottom: -2, left: 'calc(50% - 9px)', transition: theme.transitions.create('opacity'), }, }); function App(props) { const { classes } = props; const images = [ { url: 'https://firebasestorage.googleapis.com/v0/b/learn-firebase-masalib.appspot.com/o/images%2Fsite%2Fs-DSC00325.jpg?alt=media', title: 'Authentication', width: '40%', siteurl: '/screens/index', }, { url: 'https://firebasestorage.googleapis.com/v0/b/learn-firebase-masalib.appspot.com/o/images%2Fsite%2Fs-DSC00375.jpg?alt=media', title: 'Cloud FireStore', width: '20%', siteurl: '/chat/index', }, { url: 'https://firebasestorage.googleapis.com/v0/b/learn-firebase-masalib.appspot.com/o/images%2Fsite%2Fs-DSC00537.jpg?alt=media', title: 'Realtime Datebase', width: '40%', siteurl: '/screens/index3', }, { url: 'https://firebasestorage.googleapis.com/v0/b/learn-firebase-masalib.appspot.com/o/images%2Fsite%2Fs-DSC00389.jpg?alt=media', title: 'Hosting', width: '50%', siteurl: '/screens/index4', }, { url: 'https://firebasestorage.googleapis.com/v0/b/learn-firebase-masalib.appspot.com/o/images%2Fsite%2Fs-DSC00365.jpg?alt=media', title: 'Functions', width: '50%', siteurl: '/screens/index5', }, ]; return ( <Container className={classes.root} component="section"> <Typography variant="h4" marked="center" align="center" component="h2"> material-ui ButtonBase Sample </Typography> <div className={classes.images}> {images.map((image) => ( <ButtonBase key={image.title} className={classes.imageWrapper} style={{ width: image.width, }} //component={RouterLink} to={image.siteurl} > <div className={classes.imageSrc} style={{ backgroundImage: `url(${image.url})`, }} /> <div className={classes.imageBackdrop} /> <div className={classes.imageButton} > <Typography component="h3" variant="h6" color="inherit" className={classes.imageTitle} > {image.title} <div className={classes.imageMarked} /> </Typography> </div> </ButtonBase> ))} </div> </Container> ); } App.propTypes = { classes: PropTypes.object.isRequired, }; export default withStyles(styles)(App);
component={RouterLink} to={image.siteurl}の部分をコメントアウトしていますが、react-route-domのリンクとして使う場合はコンポーネントを指定する形になります。(codesanboxのプログラムだとrouteを指定していないのでコメントアウトをはずすとエラーになります)
images のパーセントの部分で横幅を計算する形になっているのが楽です。
結果
感想
- 横幅の計算が楽で感動しました
- レスポンシブで表示したときにも対応していて感動
- react-router-domを使う場合はちょっと工夫が必要だけど覚えてしまえばできる。