使用 React-Bootstrap,如何让我的 Instrument Cards 保持动态大小,同时仍然指定最小卡片大小
Using React-Bootstrap, how can i keep my Instrument Cards dynamically sized, while still specifying a minimum card size
所以,这是我的困境
这是我的卡片目前的样子:
这看起来很漂亮,但是,当你改变屏幕尺寸时,它是这样的:
这不是很好,因为我们现在想要 bootstrap 应用程序,实际上任何网站都可以响应。
我想要的是让卡片水平伸展,这样无论我们的显示器宽度是多少,卡片都会填满整个卡片组 - 即标题为 'Instrument List'[= 的底部部分17=]
现在,如果我把
style={{flexGrow: 1}}
在每张卡片上,然后它似乎有点工作,但是,并不像我真正想要的那样工作。
如果我有一排不包含 5 张卡片的卡片,它会将它们拉长:
我只希望我的卡片组能够伸展以填满整个容器,但我也希望它保持卡片的标准尺寸
这是我的 Card Deck 代码,它从 JSON 文件和 Card 项目生成乐器。
列表代码:
import InstrumentCard from './InstrumentCard'
import styles from '../styles/InstrumentList.module.scss'
import {CardDeck} from 'react-bootstrap'
const InstrumentList = ({instruments, onDel, onLoc, onShuf, onRep, onRepButClick, setRepInstrumentID}) => {
return (
<CardDeck key={1} className={styles.container} style={{display: 'flex', flexDirection: 'row'}}>
{instruments.map((instrument, i) => (
<InstrumentCard
key={i}
id={i}
instr = {instrument}
name={instrument.name}
description={instrument.description}
imagePath={instrument.image}
wikiLink={instrument.wikipedia}
tubeLink={instrument.youtube}
onDelete = {onDel}
isLocked = {instrument.locked}
onLock = {onLoc}
onShuffle = {onShuf}
onReplace = {onRep}
onRepButtonClick = {onRepButClick}
setReplacementInstrumentID = {setRepInstrumentID}
style={{flex: 1}}>
</InstrumentCard>
)) }
</CardDeck>
)
}
export default InstrumentList
卡片代码:
import {Card, Button, ButtonGroup, ButtonToolbar} from 'react-bootstrap'
import styles from '../styles/InstrumentCard.module.scss'
import {useState} from 'react'
const InstrumentCard = ({id, name, description, imagePath, wikiLink, tubeLink, onDelete, isLocked, onLock, onShuffle, setReplacementInstrumentID, onRepButtonClick}) => {
return (
<Card style={{ minWidth: '18rem', flexGrow: 1, margin:'1rem', minHeight:'32rem'}}>
<div>
<button id="lockButton" onClick={() => {onLock(id)}} className={isLocked ? styles.btnOverrideLocked : styles.btnOverride}>{isLocked ? "" : ""}</button>
<button id="shuffleButton" autoFocus={true} onClick={()=> {onShuffle(id)}} className={styles.btnOverrideShuffle} style={{float: "right"}}><span></span></button>
</div>
<Card.Img variant="top" src={imagePath} style={{padding:'1rem', maxHeight: '10rem', height:'100%', objectFit: 'contain'}} />
<Card.Body style={{display: 'flex', flexDirection: 'column', justifyContent: 'space-between'}}>
<div>
<Card.Title>{name}</Card.Title>
<Card.Text>
{description}
</Card.Text>
</div>
<div style={{marginTop: '.5rem'}}>
<ButtonGroup style={{width: "100%"}}>
<Button variant="danger" onClick={()=> onDelete(id)}>Delete</Button>
<Button variant="secondary" onClick={()=> {setReplacementInstrumentID(id); onRepButtonClick()}} >Replace</Button>
</ButtonGroup>
</div>
</Card.Body>
<Card.Footer>
<Card.Link target="_blank" rel="noopener noreferrer" href={wikiLink}>Wikipedia</Card.Link>
<Card.Link target="_blank" rel="noopener noreferrer" href={tubeLink}>Youtube</Card.Link>
</Card.Footer>
</Card>
)
}
export default InstrumentCard
非常感谢任何帮助或解释!提前致谢!
编辑:我尝试过但失败的是使用 map 并创建一个变量“let newIndex = (i*5) 并尝试使用 newIndex + 1 来获取其他索引,并尝试生成 5 bootstrap 一行中的列,但是,这不起作用,至少对于 map 函数,因为没有办法阻止 map 超过实际仪器数量,以及其他问题。
我也尝试过为我的卡片添加最大宽度和高度,但是,这仍然允许它们按行增长和收缩,这是我们不想要的
我觉得某种 bootstrap Col 和 Row 生成是理想的,但我不知道如何使用 javascript 让它每行只生成 5 个元素 return声明。
我想出办法了!
因此,基本上在我的 InstrumentList 中,我完全放弃了卡片组的使用,而只是使用 Row 元素。在 instrument.map 中,我用一个 Col 元素包围了每张乐器卡片,然后我对其应用了一些自定义样式,因为我只需要五列,而 12 不能除以 5,所以我不得不稍微捏造一下。
这是我最终的 InstrumentList
import InstrumentCard from './InstrumentCard'
import styles from '../styles/InstrumentList.module.scss'
import {CardDeck, Row, Col} from 'react-bootstrap'
const InstrumentList = ({instruments, onDel, onLoc, onShuf, onRep, onRepButClick, setRepInstrumentID}) => {
return (
<Row key={1} className={styles.container} style={{display: 'flex', flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'flex-start' }}>
{instruments.map((instrument, i) => (
<Col className={styles.properCol}>
<InstrumentCard
key={i}
id={i}
instr = {instrument}
name={instrument.name}
description={instrument.description}
imagePath={instrument.image}
wikiLink={instrument.wikipedia}
tubeLink={instrument.youtube}
onDelete = {onDel}
isLocked = {instrument.locked}
onLock = {onLoc}
onShuffle = {onShuf}
onReplace = {onRep}
onRepButtonClick = {onRepButClick}
setReplacementInstrumentID = {setRepInstrumentID}
style={{flex: 1}}>
</InstrumentCard>
</Col>
)) }
</Row>
)
}
export default InstrumentList
最终仪器卡
import {Card, Button, ButtonGroup, Col} from 'react-bootstrap'
import styles from '../styles/InstrumentCard.module.scss'
import {useState} from 'react'
const InstrumentCard = ({id, name, description, imagePath, wikiLink, tubeLink, onDelete, isLocked, onLock, onShuffle, setReplacementInstrumentID, onRepButtonClick}) => {
return (
<Card style={{minWidth: '16rem', flexGrow: 1, margin:'1rem', minHeight:'32rem'}}>
<div>
<button id="lockButton" onClick={() => {onLock(id)}} className={isLocked ? styles.btnOverrideLocked : styles.btnOverride}>{isLocked ? "" : ""}</button>
<button id="shuffleButton" autoFocus={true} onClick={()=> {onShuffle(id)}} className={styles.btnOverrideShuffle} style={{float: "right"}}><span></span></button>
</div>
<Card.Img variant="top" src={imagePath} style={{padding:'1rem', maxHeight: '10rem', height:'100%', objectFit: 'contain'}} />
<Card.Body style={{display: 'flex', flexDirection: 'column', justifyContent: 'space-between'}}>
<div>
<Card.Title>{name}</Card.Title>
<Card.Text>
{description}
</Card.Text>
</div>
<div style={{marginTop: '.5rem'}}>
<ButtonGroup style={{width: "100%"}}>
<Button variant="danger" onClick={()=> onDelete(id)}>Delete</Button>
<Button variant="secondary" onClick={()=> {setReplacementInstrumentID(id); onRepButtonClick()}} >Replace</Button>
</ButtonGroup>
</div>
</Card.Body>
<Card.Footer>
<Card.Link target="_blank" rel="noopener noreferrer" href={wikiLink}>Wikipedia</Card.Link>
<Card.Link target="_blank" rel="noopener noreferrer" href={tubeLink}>Youtube</Card.Link>
</Card.Footer>
</Card>
)
}
export default InstrumentCard
以及 InstrumentList 的样式
.container {
margin: 2rem;
}
.properCol {
flex: 0 0 20%;
max-width: 20%;
position: relative;
width: 100%;
padding: 0;
}
@media (max-width: 1400px) {
.properCol {
flex: 0 0 25%;
max-width: 25%;
position: relative;
width: 25%;
padding: 0;
}
}
@media (max-width: 1150px) {
.properCol {
flex: 0 0 33.333333%;
max-width: 33.333333%;
position: relative;
width: 33.333333%;
padding: 0;
}
}
@media (max-width: 900px) {
.properCol {
flex: 0 0 50%;
max-width: 50%;
position: relative;
width: 50%;
padding: 0;
}
}
@media (max-width: 620px) {
.properCol {
flex: 0 0 100%;
max-width: 100%;
position: relative;
width: 100%;
padding: 0;
}
}
衷心希望这对以后的其他人有所帮助!一段时间以来我不得不处理的最大的 PITA 之一。干杯!
所以,这是我的困境
这是我的卡片目前的样子:
这看起来很漂亮,但是,当你改变屏幕尺寸时,它是这样的:
这不是很好,因为我们现在想要 bootstrap 应用程序,实际上任何网站都可以响应。
我想要的是让卡片水平伸展,这样无论我们的显示器宽度是多少,卡片都会填满整个卡片组 - 即标题为 'Instrument List'[= 的底部部分17=]
现在,如果我把
style={{flexGrow: 1}}
在每张卡片上,然后它似乎有点工作,但是,并不像我真正想要的那样工作。
如果我有一排不包含 5 张卡片的卡片,它会将它们拉长:
我只希望我的卡片组能够伸展以填满整个容器,但我也希望它保持卡片的标准尺寸
这是我的 Card Deck 代码,它从 JSON 文件和 Card 项目生成乐器。
列表代码:
import InstrumentCard from './InstrumentCard'
import styles from '../styles/InstrumentList.module.scss'
import {CardDeck} from 'react-bootstrap'
const InstrumentList = ({instruments, onDel, onLoc, onShuf, onRep, onRepButClick, setRepInstrumentID}) => {
return (
<CardDeck key={1} className={styles.container} style={{display: 'flex', flexDirection: 'row'}}>
{instruments.map((instrument, i) => (
<InstrumentCard
key={i}
id={i}
instr = {instrument}
name={instrument.name}
description={instrument.description}
imagePath={instrument.image}
wikiLink={instrument.wikipedia}
tubeLink={instrument.youtube}
onDelete = {onDel}
isLocked = {instrument.locked}
onLock = {onLoc}
onShuffle = {onShuf}
onReplace = {onRep}
onRepButtonClick = {onRepButClick}
setReplacementInstrumentID = {setRepInstrumentID}
style={{flex: 1}}>
</InstrumentCard>
)) }
</CardDeck>
)
}
export default InstrumentList
卡片代码:
import {Card, Button, ButtonGroup, ButtonToolbar} from 'react-bootstrap'
import styles from '../styles/InstrumentCard.module.scss'
import {useState} from 'react'
const InstrumentCard = ({id, name, description, imagePath, wikiLink, tubeLink, onDelete, isLocked, onLock, onShuffle, setReplacementInstrumentID, onRepButtonClick}) => {
return (
<Card style={{ minWidth: '18rem', flexGrow: 1, margin:'1rem', minHeight:'32rem'}}>
<div>
<button id="lockButton" onClick={() => {onLock(id)}} className={isLocked ? styles.btnOverrideLocked : styles.btnOverride}>{isLocked ? "" : ""}</button>
<button id="shuffleButton" autoFocus={true} onClick={()=> {onShuffle(id)}} className={styles.btnOverrideShuffle} style={{float: "right"}}><span></span></button>
</div>
<Card.Img variant="top" src={imagePath} style={{padding:'1rem', maxHeight: '10rem', height:'100%', objectFit: 'contain'}} />
<Card.Body style={{display: 'flex', flexDirection: 'column', justifyContent: 'space-between'}}>
<div>
<Card.Title>{name}</Card.Title>
<Card.Text>
{description}
</Card.Text>
</div>
<div style={{marginTop: '.5rem'}}>
<ButtonGroup style={{width: "100%"}}>
<Button variant="danger" onClick={()=> onDelete(id)}>Delete</Button>
<Button variant="secondary" onClick={()=> {setReplacementInstrumentID(id); onRepButtonClick()}} >Replace</Button>
</ButtonGroup>
</div>
</Card.Body>
<Card.Footer>
<Card.Link target="_blank" rel="noopener noreferrer" href={wikiLink}>Wikipedia</Card.Link>
<Card.Link target="_blank" rel="noopener noreferrer" href={tubeLink}>Youtube</Card.Link>
</Card.Footer>
</Card>
)
}
export default InstrumentCard
非常感谢任何帮助或解释!提前致谢!
编辑:我尝试过但失败的是使用 map 并创建一个变量“let newIndex = (i*5) 并尝试使用 newIndex + 1 来获取其他索引,并尝试生成 5 bootstrap 一行中的列,但是,这不起作用,至少对于 map 函数,因为没有办法阻止 map 超过实际仪器数量,以及其他问题。
我也尝试过为我的卡片添加最大宽度和高度,但是,这仍然允许它们按行增长和收缩,这是我们不想要的
我觉得某种 bootstrap Col 和 Row 生成是理想的,但我不知道如何使用 javascript 让它每行只生成 5 个元素 return声明。
我想出办法了!
因此,基本上在我的 InstrumentList 中,我完全放弃了卡片组的使用,而只是使用 Row 元素。在 instrument.map 中,我用一个 Col 元素包围了每张乐器卡片,然后我对其应用了一些自定义样式,因为我只需要五列,而 12 不能除以 5,所以我不得不稍微捏造一下。
这是我最终的 InstrumentList
import InstrumentCard from './InstrumentCard'
import styles from '../styles/InstrumentList.module.scss'
import {CardDeck, Row, Col} from 'react-bootstrap'
const InstrumentList = ({instruments, onDel, onLoc, onShuf, onRep, onRepButClick, setRepInstrumentID}) => {
return (
<Row key={1} className={styles.container} style={{display: 'flex', flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'flex-start' }}>
{instruments.map((instrument, i) => (
<Col className={styles.properCol}>
<InstrumentCard
key={i}
id={i}
instr = {instrument}
name={instrument.name}
description={instrument.description}
imagePath={instrument.image}
wikiLink={instrument.wikipedia}
tubeLink={instrument.youtube}
onDelete = {onDel}
isLocked = {instrument.locked}
onLock = {onLoc}
onShuffle = {onShuf}
onReplace = {onRep}
onRepButtonClick = {onRepButClick}
setReplacementInstrumentID = {setRepInstrumentID}
style={{flex: 1}}>
</InstrumentCard>
</Col>
)) }
</Row>
)
}
export default InstrumentList
最终仪器卡
import {Card, Button, ButtonGroup, Col} from 'react-bootstrap'
import styles from '../styles/InstrumentCard.module.scss'
import {useState} from 'react'
const InstrumentCard = ({id, name, description, imagePath, wikiLink, tubeLink, onDelete, isLocked, onLock, onShuffle, setReplacementInstrumentID, onRepButtonClick}) => {
return (
<Card style={{minWidth: '16rem', flexGrow: 1, margin:'1rem', minHeight:'32rem'}}>
<div>
<button id="lockButton" onClick={() => {onLock(id)}} className={isLocked ? styles.btnOverrideLocked : styles.btnOverride}>{isLocked ? "" : ""}</button>
<button id="shuffleButton" autoFocus={true} onClick={()=> {onShuffle(id)}} className={styles.btnOverrideShuffle} style={{float: "right"}}><span></span></button>
</div>
<Card.Img variant="top" src={imagePath} style={{padding:'1rem', maxHeight: '10rem', height:'100%', objectFit: 'contain'}} />
<Card.Body style={{display: 'flex', flexDirection: 'column', justifyContent: 'space-between'}}>
<div>
<Card.Title>{name}</Card.Title>
<Card.Text>
{description}
</Card.Text>
</div>
<div style={{marginTop: '.5rem'}}>
<ButtonGroup style={{width: "100%"}}>
<Button variant="danger" onClick={()=> onDelete(id)}>Delete</Button>
<Button variant="secondary" onClick={()=> {setReplacementInstrumentID(id); onRepButtonClick()}} >Replace</Button>
</ButtonGroup>
</div>
</Card.Body>
<Card.Footer>
<Card.Link target="_blank" rel="noopener noreferrer" href={wikiLink}>Wikipedia</Card.Link>
<Card.Link target="_blank" rel="noopener noreferrer" href={tubeLink}>Youtube</Card.Link>
</Card.Footer>
</Card>
)
}
export default InstrumentCard
以及 InstrumentList 的样式
.container {
margin: 2rem;
}
.properCol {
flex: 0 0 20%;
max-width: 20%;
position: relative;
width: 100%;
padding: 0;
}
@media (max-width: 1400px) {
.properCol {
flex: 0 0 25%;
max-width: 25%;
position: relative;
width: 25%;
padding: 0;
}
}
@media (max-width: 1150px) {
.properCol {
flex: 0 0 33.333333%;
max-width: 33.333333%;
position: relative;
width: 33.333333%;
padding: 0;
}
}
@media (max-width: 900px) {
.properCol {
flex: 0 0 50%;
max-width: 50%;
position: relative;
width: 50%;
padding: 0;
}
}
@media (max-width: 620px) {
.properCol {
flex: 0 0 100%;
max-width: 100%;
position: relative;
width: 100%;
padding: 0;
}
}
衷心希望这对以后的其他人有所帮助!一段时间以来我不得不处理的最大的 PITA 之一。干杯!