Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使响应容器在调整大小时捕捉到图元_Javascript_Html_Css_Responsive Design - Fatal编程技术网

Javascript 使响应容器在调整大小时捕捉到图元

Javascript 使响应容器在调整大小时捕捉到图元,javascript,html,css,responsive-design,Javascript,Html,Css,Responsive Design,我有一个包含恒定宽度项的动态宽度容器div。我希望能够调整容器的大小,使其仅显示整个项目,而不会将右侧的项目切成碎片 例如,一个用户的屏幕可能显示5个项目: 如果该用户开始缩小屏幕的宽度,一旦该条宽度不再足以容纳5个完整项目,我希望它缩小到只显示4个项目 坏的: 好: 我知道使用CSS3媒体查询可以实现这一点,但我希望避免为每个不同数量的元素编写不同的断点。我还希望避免使用javascript调整大小事件处理程序,尽管我不确定没有它是否可以做到这一点。您可以让容器中的项目浮动。这样,如果

我有一个包含恒定宽度项的动态宽度容器div。我希望能够调整容器的大小,使其仅显示整个项目,而不会将右侧的项目切成碎片

例如,一个用户的屏幕可能显示5个项目:

如果该用户开始缩小屏幕的宽度,一旦该条宽度不再足以容纳5个完整项目,我希望它缩小到只显示4个项目

坏的:

好:


我知道使用CSS3媒体查询可以实现这一点,但我希望避免为每个不同数量的元素编写不同的断点。我还希望避免使用javascript
调整大小
事件处理程序,尽管我不确定没有它是否可以做到这一点。

您可以让容器中的项目浮动。这样,如果容器变小,它们将漂浮到下一行

如果您足够幸运并且知道项目的高度,可以将容器设置为固定高度并
overflow:hidden
,以使流向下一行的项目不会显示

删除:

white-space: nowrap;
来自.itemBar

text-align:justify;
到.itemContainer

这样,其他不适合的项目将落在下一行,但空间将平均分配

演示:

纯CSS(一些限制) 此解决方案基于对的修改

它涉及到重叠伪元素的复杂关系以创建边界,这可能导致解决方案对在其内可以做什么或不能做什么有一定的限制(复杂的背景将是一个问题,以及某些定位方面的必要性)。然而,它在给定的情况下起作用

一点解释

基本上,每个
.item
元素都在使用
:after
:before
元素构建自己的上/下边框部分,前者绑定到
.itemContainer
,后者绑定到
.item
本身(需要
:before
来创建行末尾的最后一位边框)。此外,
:before
也在创建“flexible”右边框的位置,以便在元素移出视图时提供所需的响应。这就是为什么
:before
必须与
项相关,以及为什么每个
:after
元素的背景必须用于“隐藏”前面
:before
元素的右边框

因为我们不知道通过css在任何给定点的“计数”是哪个元素的“最后一个”在显示中,必须显示所有
:before
元素,但我们不希望所有元素都有右边框,因此
:after
需要覆盖它们。当一个元素向下移动到下一行时,它的
:after
不再覆盖现在已成为最后显示元素的右边框,显示该边框用作整个组的“右”边框

HTML(与原始小提琴匹配)

伪元素的CSS

.itemBar {
    display: inline-block;
    width: 50%; /* some width can be set, does not need to be this */
}

.itemContainer {
    position: relative; /* :after pseudo-elements are positioned off this */
    z-index: 1; /* needed for pseudo-element interaction */
    overflow: hidden;
    display: inline-block;
    max-height: 68px;
    width: 100%;
    border-left: 1px solid black; /* left border is supplied by this */
}

.item {
    width: 60px;
    height: 62px;
    display: inline-block;
    margin: 2px;
    border: 1px solid black;
    /* NOTE: CANNOT be given positioning  */
}
.item::after {
    content: '';
    position: absolute; /* will position off itemContainer */
    z-index: -1; /* push it to the background */
    top: 0; /* set it to top of itemContainer */
    bottom: 0; /* set it to bottom of itemContainer */
    margin-left: -100%; /* shove it past the far left edge of itemContainer */
    /* next, use padding to bring it back to its position at the end
       of the text string of .item */
    padding-left: 100%;
    /* next, add enough padding on the right to compensate for the right
       padding, right margin, and right border of .item */
    padding-right: 3px; 
    /* next, create the top and bottom border of "container", 
       in conjunction with the :before; so this is a pseudo-border for 
       .itemContainer being created by the .item elements */
    border-top: 1px solid black;
    border-bottom: 1px solid black;
    background: #fff; /* hide other :before borders */
}

.item:before { /* make right border */
    content: '';
    padding-top: 66px; /* give it .itemContainer height minus border heights */
    width: 100%;
    margin-top: -3px; /* .item top margin + border width */
    margin-left: -100%; /* pull the text in .item back into position */
    margin-right: 0;
      /* next, push this behind the background with an even lower z-index
        to hide it if it is not the right most element beign used to 
        form the right border */   
    z-index: -2;
    float: right; /* get the before element to the right */
    position: relative; /* needs to be adjusted in position */
    right: -4px; /* move it same as padding-right of the after element */
    display: block; /* give it a display */
      /*  next, use it to build the fake right border and also the fake
          final top/bottom borders of the of itemContainer */
    border-right: 1px solid black;
    border-top: 1px solid black;
    border-bottom: 1px solid black;
}

还有一个解决方案比ScottS的简单一点。它不需要任何定位或使用
::before
::after
,而是依赖于
::第一行
不会超过最后一个可见项的事实

加价 结果


在Safari、Chrome、Firefox和IE 11中测试。

是的,浮动元素,修复容器高度+隐藏溢出。这会导致部分元素不显示,但容器右侧仍会有空白,对吗?是的,此解决方案不会缩放元素以使用可用空间。据我所知,没有一个解决方案可以只用HTML和CSS来解决这个问题。你当然可以用JavaScript来解决这个问题,但是——考虑到我不知道你对这个功能的使用——我宁愿选择一个简单的解决方案。如果容器(
itemContainer
在jsfiddle中)没有边框。另外,如果您需要针对不同的设备进行优化,请选择宽度,以便元素在大多数分辨率下填充空间。我认为您需要更复杂的东西,可能需要JS。可能有一个库支持此功能。@Enzino与Stefan Henze的答案相同。这会导致一个大的空spa容器右侧的ce。我希望容器在无法容纳其他元素时收缩。很高兴它解决了问题。我可以将我的答案标记为正确吗?:)是的,当然可以,但请注意应用*display:inline;缩放:1;为了在ie7中正常工作。我还想补充一点,一旦视口大小超过1336px,就会在父容器中显示空白。太棒了。还不完全确定这是如何工作的,但它正是我所需要的。@jbabey:我添加了一个更新,其中有一些解释,以帮助您更好地理解“这是如何工作的”
.item::after {
    content: '';
    position: absolute; /* will position off itemContainer */
    z-index: -1; /* push it to the background */
    top: 0; /* set it to top of itemContainer */
    bottom: 0; /* set it to bottom of itemContainer */
    margin-left: -100%; /* shove it past the far left edge of itemContainer */
    /* next, use padding to bring it back to its position at the end
       of the text string of .item */
    padding-left: 100%;
    /* next, add enough padding on the right to compensate for the right
       padding, right margin, and right border of .item */
    padding-right: 3px; 
    /* next, create the top and bottom border of "container", 
       in conjunction with the :before; so this is a pseudo-border for 
       .itemContainer being created by the .item elements */
    border-top: 1px solid black;
    border-bottom: 1px solid black;
    background: #fff; /* hide other :before borders */
}

.item:before { /* make right border */
    content: '';
    padding-top: 66px; /* give it .itemContainer height minus border heights */
    width: 100%;
    margin-top: -3px; /* .item top margin + border width */
    margin-left: -100%; /* pull the text in .item back into position */
    margin-right: 0;
      /* next, push this behind the background with an even lower z-index
        to hide it if it is not the right most element beign used to 
        form the right border */   
    z-index: -2;
    float: right; /* get the before element to the right */
    position: relative; /* needs to be adjusted in position */
    right: -4px; /* move it same as padding-right of the after element */
    display: block; /* give it a display */
      /*  next, use it to build the fake right border and also the fake
          final top/bottom borders of the of itemContainer */
    border-right: 1px solid black;
    border-top: 1px solid black;
    border-bottom: 1px solid black;
}
<div class="itemContainer">
  <div class="item">1</div><div
  class="item">2</div><div
  class="item">3</div><div
  class="item">4</div><div
  class="item">5</div><div 
  class="item">6</div><div 
  class="item">7</div><div 
  class="item">8</div><div 
  class="item">9</div><div 
  class="item">10</div>
</div>
.itemContainer {
    overflow: hidden;
    height: 70px; /* .item's offset height + margin */
    /* you can constrain the width of this any way you like */
}
.itemContainer::first-line {
    font-size: 70px; /* needs to be at least as big as .wrap height */
    line-height: 0px; /* fixes oddities in Firefox */
    background: black; /* "border" color */
}
.item {
    display: inline-block;
    vertical-align: text-top; /* this minimizes the font-size required  above */
    margin: 10px; /* include desired "border" size of .itemContainer */
    box-shadow: 0 0 0 9px white; /* spread = desired margin */
    background: white; /* needs an opaque background */
    /* reset font-size and line-height */
    font-size: 1rem;
    line-height: 1.5;
    /* set your item size and borders however you like */       
    height: 50px;
    width: 50px;
    border: 1px solid red;
    box-sizing: border-box;
}
.item::first-line {
    font-size: 1rem; /* fix IE precedence */
}
.item + .item {
    margin-left: 0; /* inline-block margins don't collapse */
}