最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Make cards and images the same size - how can I do it with CSS? - Stack Overflow

programmeradmin3浏览0评论

I'm using react. Material-ui is for Cards. For Grid I'm using CSS Grid Layout. So far it looks like this:

But my goal is something like this:

And I have 2 problems:

  1. I want to have all these cards the same height (415px). I tried height: 415px on .BeerListingScroll-info-box but it doesn't work.

  2. Images of bottles and kegs are diffrent in size [keg (80px x 160px) vs. bottle (80px x 317px)]. Is there any way to make them more similar in rendered size?

-

Code:

BeerListingScroll

import React, { Component } from 'react';
import ReduxLazyScroll from 'redux-lazy-scroll';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchBeers } from '../../actions/';

import BeersListItem from '../../ponents/BeersListItem';
import ProgressIndicator from '../../ponents/ProgressIndicator';

import './style.css';

class BeerListingScroll extends Component {
  constructor(props) {
    super(props);

    this.loadBeers = this.loadBeers.bind(this);
  }

  loadBeers() {
    const { skip, limit } = this.props.beers;
    this.props.fetchBeers(skip, limit);
  }

  render() {
    const { beersArray, isFetching, errorMessage, hasMore } = this.props.beers;
    return (
      <div className="container beers-lazy-scroll">
        <ReduxLazyScroll
          isFetching={isFetching}
          errorMessage={errorMessage}
          loadMore={this.loadBeers}
          hasMore={hasMore}
        >
          <div className="BeerListingScroll-wrapper">
            {beersArray.map(beer => (
              <div key={beer.id} className="BeerListingScroll-info-box">
                <BeersListItem beer={beer} />
              </div>
            ))}
          </div>
        </ReduxLazyScroll>
        <div className="row beers-lazy-scroll__messages">
          {isFetching && (
            <div className="alert alert-info">
              <ProgressIndicator />
            </div>
          )}

          {!hasMore &&
            !errorMessage && (
              <div className="alert alert-success">
                All the beers has been loaded successfully.
              </div>
            )}
        </div>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    beers: state.beers,
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ fetchBeers }, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(BeerListingScroll);

BeerListingScroll css

.BeerListingScroll-wrapper {
  display: grid;
  margin: 0;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr) ) ;
  background-color: #f7f7f7;
}

.BeerListingScroll-info-box {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
  color: #fff;
  border-radius: 5px;
  padding: 20px;
  font-size: 150%;
  width: 320px;
}


/* This applies from 600px onwards */
@media (min-width: 1820px) {
  .BeerListingScroll-wrapper {
    margin: 0 400px;
  }
}

@media (min-width: 1620px) {
  .BeerListingScroll-wrapper {
    margin: 0 300px;
  }
}

@media (min-width: 1366px) {
  .BeerListingScroll-wrapper {
    margin: 0 200px;
  }
}

BeerListItem is the child of BeerListingScroll

import React from 'react';
import Card, { CardContent } from 'material-ui/Card';
import Typography from 'material-ui/Typography';

function BeerListItem(props) {
  return (
    <div>
      <Card raised>
        <CardContent>
          <img src={props.beer.image_url} alt="beer" width="30%" />
          <Typography variant="headline" ponent="h2">
            {props.beer.name}
          </Typography>
          <Typography ponent="p">{props.beer.tagline}</Typography>
        </CardContent>
      </Card>
    </div>
  );
}

export default BeerListItem;

Full project on github -> Github

I'm using react. Material-ui is for Cards. For Grid I'm using CSS Grid Layout. So far it looks like this:

But my goal is something like this:

And I have 2 problems:

  1. I want to have all these cards the same height (415px). I tried height: 415px on .BeerListingScroll-info-box but it doesn't work.

  2. Images of bottles and kegs are diffrent in size [keg (80px x 160px) vs. bottle (80px x 317px)]. Is there any way to make them more similar in rendered size?

-

Code:

BeerListingScroll

import React, { Component } from 'react';
import ReduxLazyScroll from 'redux-lazy-scroll';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchBeers } from '../../actions/';

import BeersListItem from '../../ponents/BeersListItem';
import ProgressIndicator from '../../ponents/ProgressIndicator';

import './style.css';

class BeerListingScroll extends Component {
  constructor(props) {
    super(props);

    this.loadBeers = this.loadBeers.bind(this);
  }

  loadBeers() {
    const { skip, limit } = this.props.beers;
    this.props.fetchBeers(skip, limit);
  }

  render() {
    const { beersArray, isFetching, errorMessage, hasMore } = this.props.beers;
    return (
      <div className="container beers-lazy-scroll">
        <ReduxLazyScroll
          isFetching={isFetching}
          errorMessage={errorMessage}
          loadMore={this.loadBeers}
          hasMore={hasMore}
        >
          <div className="BeerListingScroll-wrapper">
            {beersArray.map(beer => (
              <div key={beer.id} className="BeerListingScroll-info-box">
                <BeersListItem beer={beer} />
              </div>
            ))}
          </div>
        </ReduxLazyScroll>
        <div className="row beers-lazy-scroll__messages">
          {isFetching && (
            <div className="alert alert-info">
              <ProgressIndicator />
            </div>
          )}

          {!hasMore &&
            !errorMessage && (
              <div className="alert alert-success">
                All the beers has been loaded successfully.
              </div>
            )}
        </div>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    beers: state.beers,
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ fetchBeers }, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(BeerListingScroll);

BeerListingScroll css

.BeerListingScroll-wrapper {
  display: grid;
  margin: 0;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr) ) ;
  background-color: #f7f7f7;
}

.BeerListingScroll-info-box {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
  color: #fff;
  border-radius: 5px;
  padding: 20px;
  font-size: 150%;
  width: 320px;
}


/* This applies from 600px onwards */
@media (min-width: 1820px) {
  .BeerListingScroll-wrapper {
    margin: 0 400px;
  }
}

@media (min-width: 1620px) {
  .BeerListingScroll-wrapper {
    margin: 0 300px;
  }
}

@media (min-width: 1366px) {
  .BeerListingScroll-wrapper {
    margin: 0 200px;
  }
}

BeerListItem is the child of BeerListingScroll

import React from 'react';
import Card, { CardContent } from 'material-ui/Card';
import Typography from 'material-ui/Typography';

function BeerListItem(props) {
  return (
    <div>
      <Card raised>
        <CardContent>
          <img src={props.beer.image_url} alt="beer" width="30%" />
          <Typography variant="headline" ponent="h2">
            {props.beer.name}
          </Typography>
          <Typography ponent="p">{props.beer.tagline}</Typography>
        </CardContent>
      </Card>
    </div>
  );
}

export default BeerListItem;

Full project on github -> Github

Share Improve this question asked Mar 16, 2018 at 15:25 MountainConquerorMountainConqueror 6023 gold badges9 silver badges28 bronze badges 5
  • 2 this may just be a HTML + CSS questions -- could you also include the rendered HTML code as it is generated on the web page? – Doug Commented Mar 16, 2018 at 15:28
  • But really -- find the element that is the white background and set the height of the div to that -- if it won't adjust use the web developer tool bar to see if there are any styles overwriting your intent – Doug Commented Mar 16, 2018 at 15:29
  • use flexbox - ideal for equal height rows. but as you haven't create an minimal reproducible example, I'm voting to close – Pete Commented Mar 16, 2018 at 15:30
  • You are encountering an artwork problem! Anytime you change the aspect ratios to make images scale, you e across the problem of distorting the images, for a truly professional look you refactor the artwork, so the images are uniform. – Matthew Lagerwey Commented Mar 16, 2018 at 16:23
  • Your best bet is to use CSS background. It offers the cover and some other nice, easy functionality. See MDN's Scaling background images – Ronnie Smith Commented Mar 16, 2018 at 17:09
Add a ment  | 

3 Answers 3

Reset to default 6

So for image sizes here I got great answer.

And I added:

.BeerListItem-img {
  height: auto;
  max-height: 250px;
  width: auto;
  max-width: 250px;
}

And for card size I just added inside BeerListItem class to Card like so (.BeerListItem-main-card):

function BeerListItem(props) {
  return (
    <div>
      <Card raised className="BeerListItem-main-card">
        <CardContent>
          <img
            src={props.beer.image_url}
            alt="beer"
            className="BeerListItem-img"
          />
          <Typography variant="headline" ponent="h2">
            {props.beer.name}
          </Typography>
          <Typography ponent="p">{props.beer.tagline}</Typography>
        </CardContent>
      </Card>
    </div>
  );
}

And here is corresponding css to that ponent.

.BeerListItem-main-card {
  width: 320px;
  height: 415px;
}

.BeerListItem-img {
  height: auto;
  max-height: 250px;
  width: auto;
  max-width: 250px;
}

With that two changes, I've managed to achieve my goal.

You should try exploring display:flex;

Here is a link to a fantastic code pen that may help you achieve what you want:

https://codepen.io/enxaneta/full/adLPwv

More specifically here is an example I've created with what you might be trying to achieve.

https://jsfiddle/dalecarslaw/sxdr3eep/

Here is the areas of code you should focus on:

  display:flex;
  align-items:space-between;
  justify-content:space-between;
  flex-wrap:wrap;

by using display flex, my humble suggestion is adding "flex:1" to parent element of the card. This will allow your display to set the same size to each children and with that auto adjust each card to the same size, including the img.

I solved that, using that property.

发布评论

评论列表(0)

  1. 暂无评论