Bootstrap 4 card deck table-cell columns responsiv

2019-03-20 12:30发布

问题:

So in Bootstrap v4, I see there's a new feature for card decks ( http://v4-alpha.getbootstrap.com/components/card/#decks ) that makes a group of cards, with their height equal according to the tallest content in the group.

It appears the number of columns are based on how many card-div's are in the group. Is there a way to make the number of columns change based on the viewport? For example, 4 columns / card wide at large width, 2 wide at medium width, and 1 at small width?

Currently they stay the same number of columns/cards wide until less than 544px. At 544px and greater, they have display: table-cell with the screen (min-width: 544px) rule.

Is there a way to make the cards have different numbers of columns based on viewport by changing only the CSS?

Edit - Looking to not use flex / flexbox due to IE support

Codepen example of 4 col/card wide and 3 col/card wide at http://codepen.io/jpost-vlocity/full/PNEKKy/

回答1:

Update 2018

It's hard to set the cards widths (responsive) with card-deck because it uses display:table-cell and width:1%.

I found it easier to make them responsive using the cards inside the Bootstap grid col-* and then you can use the grid viewport breakpoints. Enable Bootstrap's flexbox if you want the cards to be equal height like the card-deck.

http://www.codeply.com/go/6eqGPn3Qud

Also, img-responsive has changed to img-fluid

Bootstrap 4.0.0

Flexbox is now the default, but there is still not a supported way to make responsive card-deck's. The recommended way is to use cards inside the grid:

Responsive cards using grid

Another way to make a responsive card-deck, is using responsive reset divs every x columns. This will force cards to wrap at specific breakpoints.

For example: 5 on xl, 4 on lg, 3 on md, 2 on sm, etc..

Responsive card deck demo (4.0.0)
Responsive card deck demo (alpha 6)
CSS pseudo elements variation



回答2:

Here you go, http://codepen.io/KarlDoyle/pen/pypWbR

The main thing is that you have to override the styles. as shown below.

.card-deck {
  display: flex;
  justify-content: flex-start;
  flex-flow: row wrap; 
  align-items: stretch;
}
.card-deck .card {
  display: block;
  flex-basis: 33.3%; /* change this value for each breakpoint*/
}


回答3:

I found a pretty easy workaround using css-grid. You could tweak the 250px to fit your use case.

.card-deck {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    grid-gap: .5rem;
}


回答4:

Bootstrap 4 card deck responsive

I tried to use the <container>, <row> and <col> to make it responsive, but you lose the

All the cards have the same height

feature of the card deck, if you do that. What you need is CSS:

.card-deck {
  margin: 0 -15px;
  justify-content: space-between;
}

.card-deck .card {
  margin: 0 0 1rem;
}

@media (min-width: 576px) and (max-width: 767.98px) {
  .card-deck .card {
    -ms-flex: 0 0 48.7%;
    flex: 0 0 48.7%;
  }
}

@media (min-width: 768px) and (max-width: 991.98px) {
  .card-deck .card {
    -ms-flex: 0 0 32%;
    flex: 0 0 32%;
  }
}

@media (min-width: 992px)
{
  .card-deck .card {
    -ms-flex: 0 0 24%;
    flex: 0 0 24%;
  }
}

Here is my CodePen: Bootstrap 4 card deck responsive



回答5:

This can be done with javascript.

  • First you need to create divs for each breakpoint in your html document.

  • Then you need to assign the divs a default value in css. Create media queries for each breakpoint that override that default value

  • Then write a some javascript. One function to test for the breakpoints by checking if the default css value you assigned has been overridden, and another to add and remove appropriate classes. I removed the card-deck-wrapper and card-deck classes when I wanted to make them responsive, and added the appropriate col-**-** classes. Finally, add calls to these functions in the document.ready and window.resize areas.

var breakpoint;

$(document).on('ready', function() {
	detectBreakpoint();
});

$(window).resize(function() {
	detectBreakpoint();
});

// detects the current breakpoint
function detectBreakpoint() {
	if ($('.breakpointXS').css('display') == "inline") {
		breakpoint = 'xs';
	} else if ($('.breakpointSM').css('display') == "inline") {
		breakpoint = 'sm';
	} else if ($('.breakpointMD').css('display') == "inline") {
		breakpoint = 'md';
	} else if ($('.breakpointLG').css('display') == "inline") {
		breakpoint = 'lg';
	}
	placeCards();
}

function placeCards() {
	if (breakpoint == 'xs' || breakpoint == 'sm') {
		console.log('small');
		$('.cardCont1').removeClass('card-deck-wrapper');
		$('.cardCont2').removeClass('card-deck');
		$('.card').addClass('col-xs-10 offset-xs-1');
	} else {
		$('.cardCont1').addClass('card-deck-wrapper');
		$('.cardCont2').addClass('card-deck');
		$('.card').removeClass('col-xs-10 offset-xs-1');	
	}
}
.breakpointXS, .breakpointSM, .breakpointMD, .breakpointLG {
	/* hides divs to detect breakpoints until made visible my media queries */
	display: none;
}

@media only screen and (max-width: 767px) {
	.breakpointXS {
		display: inline;
	}
}

@media screen and (max-width: 991px) and (min-width: 768px) {
	.breakpointSM {
		display: inline;
	}
}

@media screen and (max-width: 1199px) and (min-width: 992px) {
	.breakpointMD {
		display: inline;
	}
}

@media only screen and (min-width: 1200px) {
	.breakpointLG {
		display: inline;
	}
}
<!-- to use breakpoints in jquery -->
		<div class="breakpointXS"></div>
		<div class="breakpointSM"></div>
		<div class="breakpointMD"></div>
		<div class="breakpointLG"></div>