作者热门文章
- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
我想使用 flexbox(没有媒体查询)实现响应式网格状布局。网格中可以有可变数量的元素。每个元素都应具有固定且相等的宽度。元素应左对齐。整个组的左右边距应该相等。
它应该是这样的:
我是这样实现的:
.container {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
margin: auto;
}
.item {
height: 200px;
width: 200px;
background-color: purple;
padding: 10px;
margin: 10px;
}
<div class="container">
<div class="item">Flex item 1</div>
<div class="item">Flex item 2</div>
<div class="item">Flex item 3</div>
<div class="item">Flex item 4</div>
<div class="item">Flex item 5</div>
</div>
没用:
我希望在容器上设置 margin: auto
会强制它的宽度刚好足以容纳每行中的最佳元素数。
我知道我可以使用像 Bootstrap 或 Foundations 这样的框架轻松实现它,但我想知道是否也可以使用 flexbox。
最佳答案
CSS 网格解决方案是唯一优雅且灵活的 CSS 解决方案。
.container {
display: grid;
grid-template-columns: repeat(auto-fill, 200px);
grid-auto-rows: 200px;
grid-gap: 10px;
justify-content: center;
}
.item {
background-color: purple;
padding: 10px;
}
<div class="container">
<div class="item">Flex item 1</div>
<div class="item">Flex item 2</div>
<div class="item">Flex item 3</div>
<div class="item">Flex item 4</div>
<div class="item">Flex item 5</div>
</div>
不幸的是,它没有最好的浏览器支持,所以如果您需要像 IE 这样过时的浏览器,您将不得不使用 Javascript 来实现这一点。这是因为 flexbox 容器占据了所有宽度,即使元素没有。
所以基本上我们正在计算 margin-left
所需的值以使我们的 flexbox 元素居中。无论初始标记设置如何,此 Javascript 都应该有效。
// get width of element with margins
function getOuterWidth(el) {
var styles = window.getComputedStyle(el);
var margins = parseFloat(styles["marginLeft"]) +
parseFloat(styles["marginRight"]);
return Math.ceil(el.getBoundingClientRect().width + margins);
}
// get width of element without paddings
function getContentWidth(el) {
var styles = window.getComputedStyle(el);
var paddings = parseFloat(styles["paddingLeft"]) +
parseFloat(styles["paddingRight"]);
return Math.ceil(el.getBoundingClientRect().width - paddings);
}
// Get top of element
function getTopOfElement(el) {
return el.getBoundingClientRect().top;
}
var container = document.querySelector(".container");
var initialMarginLeft = parseFloat(window.getComputedStyle(container)["marginLeft"]);
// getting array of items
var items = Array.prototype.slice.call(document.querySelectorAll(".item"));
function centerItems() {
if (items.length === 0) return 0;
// set margin-left to initial value to recalculate it
container.style.marginLeft = initialMarginLeft + "px";
var topOfFirstItem = getTopOfElement(items[0]);
var spaceTakenByElementsOnFirstLine = getOuterWidth(items[0]);
for (var i = 1; i < items.length; i++) {
// Break in case we are in second line
if (getTopOfElement(items[i]) > topOfFirstItem)
break;
spaceTakenByElementsOnFirstLine += getOuterWidth(items[i]);
}
// Set margin-left to center elements
var marginLeft = initialMarginLeft + (getContentWidth(container) - spaceTakenByElementsOnFirstLine) / 2;
container.style.marginLeft = marginLeft + "px";
};
window.addEventListener("resize", centerItems);
centerItems();
.container {
display: flex;
flex-wrap: wrap;
}
.item {
height: 200px;
width: 200px;
background-color: purple;
padding: 10px;
margin: 10px;
}
<div class="container">
<div class="item">Flex item 1</div>
<div class="item">Flex item 2</div>
<div class="item">Flex item 3</div>
<div class="item">Flex item 4</div>
<div class="item">Flex item 5</div>
</div>
// get width of element with margins
function getOuterWidth(el) {
return $(el).outerWidth(true);
}
// get width of element without paddings
function getContentWidth(el) {
return parseFloat($(el).css("width"));
}
function getTopOfElement(el) {
return $(el).position().top;
}
var $container = $(".container");
var $items = $(".item");
var initialMarginLeft = parseFloat($container.css("margin-left"));
function centerItems() {
if ($items.length === 0) return 0;
// set margin-left to initial value to recalculate it
$container.css("margin-left", initialMarginLeft + "px");
var topOfFirstItem = getTopOfElement($items[0]);
var spaceTakenByElementsOnFirstLine = getOuterWidth($items[0]);
for (var i = 1; i < $items.length; i++) {
// Break in case we are in second line
if (getTopOfElement($items[i]) > topOfFirstItem)
break;
spaceTakenByElementsOnFirstLine += getOuterWidth($items[i]);
}
// Set margin left to center elements
var marginLeft = initialMarginLeft + (getContentWidth($container) - spaceTakenByElementsOnFirstLine) / 2;
$container.css("margin-left", marginLeft + "px");
};
$(window).resize(centerItems);
centerItems();
.container {
display: flex;
flex-wrap: wrap;
}
.item {
height: 200px;
width: 200px;
background-color: purple;
padding: 10px;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item">Flex item 1</div>
<div class="item">Flex item 2</div>
<div class="item">Flex item 3</div>
<div class="item">Flex item 4</div>
<div class="item">Flex item 5</div>
</div>
关于css - 带 flexbox 的左对齐和居中网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32572347/
我是一名优秀的程序员,十分优秀!