如何围绕某些兄弟HTML元素绘制一个框?

时间:2015-04-26 19:49:23

标签: html css

我想直观地突出显示一组共享相同属性的兄弟元素。



#boxed_contents span[data-boxme] {
  display: inline-block;
  border: 2px solid #00F;
  border-radius: 5px;
}

<div id="boxed_contents">
    <span>hello</span><!--
 --><span>world</span><!--
 --><span data-boxme>look</span><!--
 --><span data-boxme>at</span><!--
 --><span data-boxme>me</span>
</div>
&#13;
&#13;
&#13;

这个几乎就像我想要的那样工作,但是我想加入每个boxme元素周围的框,只留下一个框围绕所有三个元素。我知道我可以将相邻的boxme元素包装在包装div中,但由于这在概念上是一种视觉(而不是结构)选择,所以我真的很想在不修改HTML的情况下这样做。

有没有办法在纯CSS中执行此操作?没错,加上一些简单的Javascript?

4 个答案:

答案 0 :(得分:7)

实际上,不可能通过纯CSS将元素包装在另一个元素中。但是我们可以通过在每个相邻元素上添加边框并在中间边框上放置绝对定位的伪元素来以某种方式伪造效果。

除此之外,请注意自定义属性在HTML中无效,除非它们的格式为data-*

if (getc(fp) == EOF){
    break;
}
#boxed_contents [data-boxme] {
  display: inline-block;
  border: 2px solid #00F;
}

#boxed_contents [data-boxme] + [data-boxme] {
  margin-left: -.25em;
  padding-left: .25em;
  position: relative;
}

#boxed_contents [data-boxme] + [data-boxme]:after {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: -4px;
  width: 4px;
  background: white;
}

答案 1 :(得分:1)

感谢Hashem让我与兄弟选择器一起使用(以独特地设置连续元素的样式),以及用于添加边框元素的伪选择器。

我必须添加一行JavaScript,以确保在最后没有span属性的空白boxme元素。通过这样做,我可以在:before元素后面的任何非boxme元素上使用boxme伪元素。这个策略的主要优点(比Hashem给出的那个)是我可以保留原始CSS的圆角。

&#13;
&#13;
document.getElementById('boxed_contents').appendChild(document.createElement('span'));
&#13;
#boxed_contents span[data-boxme] {
  border: 2px solid #00F;
  border-right: none;
  border-radius: 5px 0 0 5px;
  padding-left: 4px;
}
#boxed_contents span[data-boxme] + span[data-boxme] {
  border-left: none;
  border-radius: 0;
  padding-left: 0;
}
#boxed_contents span[data-boxme] + span:not([data-boxme]):before {
  content: "";
  border: 2px solid #00F;
  border-left: none;
  border-radius: 0 5px 5px 0;
  padding-right: 4px;
}
&#13;
<div id="boxed_contents">
    <span>hello</span><!--
 --><span>world</span><!--
 --><span data-boxme>look</span><!--
 --><span data-boxme>at</span><!--
 --><span data-boxme>me</span>
</div>
&#13;
&#13;
&#13;

我不确定此解决方案是如何跨平台的,但它似乎在我的Chrome目标平台上运行良好。

答案 2 :(得分:1)

this是否适合您?

var borderProps='2px solid #f00',borderRadius='5px',boxMeAttr='data-boxme';
var spans=document.querySelectorAll('span'),boxMeArrays=[],dummyArray=null,iterator=0;
var currSpan=null,prevSpan=null;
var i,length=spans.length,adjacentSpans=0;
for(i=0; i<length; i+=1){
    prevSpan=currSpan;
    currSpan=spans[i];
    if(currSpan.hasAttribute(boxMeAttr)){
        if(prevSpan!==null&&prevSpan.hasAttribute(boxMeAttr)){
            dummyArray[dummyArray.length]=currSpan;
        }else{
            dummyArray=[currSpan];
            boxMeArrays[iterator]=dummyArray;
            iterator+=1;
        }
    }
}
length=boxMeArrays.length;
for(i=0; i<length; i+=1){
    adjacentSpans=boxMeArrays[i].length;
    for(var j=0; j<adjacentSpans; j+=1){
        currSpan=boxMeArrays[i][j];
        if(adjacentSpans>1){
            if(j===0){
                currSpan.innerText+=' ';
                currSpan.style.borderLeft=currSpan.style.borderTop=currSpan.style.borderBottom=borderProps;
                currSpan.style.borderTopLeftRadius=currSpan.style.borderBottomLeftRadius=borderRadius;
            }else if(j===adjacentSpans-1){
                currSpan.style.borderTop=currSpan.style.borderBottom=currSpan.style.borderRight=borderProps;
                currSpan.style.borderTopRightRadius=currSpan.style.borderBottomRightRadius=borderRadius;
            }else{
                currSpan.innerText+=' ';
                currSpan.style.borderTop=currSpan.style.borderBottom=borderProps;
            }
        }else{
            currSpan.style.border=borderProps;
            currSpan.style.borderRadius=borderRadius;
        }
    }
}

绝对不是直截了当但我觉得它足够好。如果你对它好的话,只需要一点修改你的HTML:使用innerText添加一个额外的空间,这样边框可以很好地相互连接。

查看jsFiddle上的实施情况。希望我没有错过任何细节,并希望这个解决方案适合你。

答案 3 :(得分:-1)

我已经编辑了您的代码,以便按照您描述的方式工作,class元素中的.boxme标记应用boxme类位于#box_contents标记内的样式。

#boxed_contents.boxme {
  display: inline-block;

}
#boxed_contents.borderBox {
border: 2px solid #00F;
      border-radius: 5px;
}

:)

    <div id="boxed_contents">
      <span>hello</span>
      <span>world</span>
<div class='borderBox'>
      <span class='boxme'>look</span>
      <span class='boxme'>at</span>
      <span class='boxme'>me</span>
    </div>
</div>

如果你知道boxme结构的布局,那么你可以通过在所选元素周围添加额外的DIV来强制它。