只用纯CSS创建水平折叠手风琴

3
我有以下4个部分:

enter image description here

当悬停在第1个元素上时,它变成了:

enter image description here

也就是说,我使用“~”选择器在悬停第1个元素时,更改了下一个元素的CSS。
/* hover on 1 */
#pillar1:hover {
width: 64%;
}
#pillar1:hover ~ #pillar2{
width: 12%;
}
#pillar1:hover ~ #pillar3{
width: 12%;
}
#pillar1:hover ~ #pillar4{
width: 12%;
}

但是当使用以下代码悬停在下一部分时:
/* hover on 2 */
#pillar2:hover {
width: 64%;
}
#pillar2:hover ~ #pillar1{
width: 12%;
}
#pillar2:hover ~ #pillar3{
width: 12%;
}
#pillar2:hover ~ #pillar4{
width: 12%;
}

转换没有发生。
HTML
 <section class="pillars">

<div id="pillar1"></div>
    <div id="pillar2"></div>
<div id="pillar3"></div>
<div id="pillar4"></div>
</section>

我该如何做到这一点?

1
please post your HTML too - Ejaz
~ 选择器仅选取后续的同级元素。https://developer.mozilla.org/zh-CN/docs/Web/CSS/General_sibling_selectors - Mathias
这个不起作用的原因是 ~ 运算符选择右侧选择器中出现在左侧选择器(具有相同父级)之后的元素。它对 pillar1 起作用,因为其他支柱都出现在它之后,但对其他任何支柱都不起作用。然而,使用 ~ 不是一个好主意,因为有更简单的方法来做到这一点。 - gandaliter
@gandaliter 我该怎么做呢? - Varun
看我的答案,有一种可能的方法。 - gandaliter
5个回答

8

当你使用 ~ 时,它将选择在悬停元素之后跟随的元素,因此只需要一个属性即可完成工作,即

display: flex;

演示

HTML

<div class="wrap">
    <div></div>
    <div></div>
    <div></div>
</div>

CSS

* {
    margin: 0;
    padding: 0;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

.wrap {
    display: flex;
}

.wrap > div {
    height: 100px;
    width: 33%;
    flex: 1;
    border: 1px solid #f00;
    -webkit-transition: flex .5s;
    transition: flex .5s;
}

.wrap > div:hover {
    flex: 3;
}

3
我认为你可以采用以下类似的解决方法:

我认为你可以采用以下类似的解决方法:

.pillars > div {
  width: 25%;
  float:left;
  ...
}
.pillars:hover > div {
  width:12%;
}
.pillars > div:hover {
  width: 64%;
}

演示。

我们需要通过一种变通的方法来实现它,这是因为我们无法使用CSS3选择器向后遍历。也就是说,当你悬停在一个列表项上时,你不能向后遍历前面的列表项以将它们的宽度设置为12%。但是,悬停在列表项上也会触发父容器的悬停。因此,我们可以通过在父容器上悬停时将width:12%设置为所有列表项来使其正常工作。


这可能是最明显的解决方案,但它实际上存在一个问题:浏览器有时会无法四舍五入值,结果会导致在转换运行时最后一个元素进入第二行。 - user652649
是的,那就是我注意到的行为。 - Mr. Alien
是的,在列表项之间快速悬停可能会因为过渡时间而产生间隙(最后一个)。我们应该使用Alien先生提供的现代解决方案,使用flex布局或SW4提供的兼容解决方案,使用表格布局。 - King King

1

更新:演示 Fiddle

HTML

<div class='expanded'></div>
<div></div>
<div></div>
<div></div>

CSS

html, body {
    width:100%;
    padding:0;
    margin:0;
}
div {
    float:left;
    width:12%;
    height:100px;
    border:1px solid red;
    background:lightgrey;
    transition:width 100ms ease-in;
    box-sizing:border-box;
}
.expanded {
    width:64%;
}

jQuery

$("div").hover(

function () {
    $("div").removeClass("expanded");
    $(this).addClass("expanded");
}, function () {
    $("div").removeClass("expanded");
    $("div:first").addClass("expanded");
});

替代方案

HTML

<div class="table">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>

CSS

html, body {
    width:100%;
    padding:0;
    margin:0;
}
.table {
    display:table;
    height:100px;
    width:100%;
}
.table div {
    display:table-cell;
    width:12%;
    border:1px solid red;
    background:lightgrey;
    transition:width 100ms ease-in;
}
.table div:hover {
    width:64%;
}

1
OP有4个div,看起来总宽度应该是“100%”,因此每个div在正常状态下为“25%”。 - King King
每次总宽度应为100%。 - Varun
其实不完全是这样的,你看例子中 div 之间的空隙了吗?如果他将总宽度设置为 100%,那么会导致溢出。应该使用 calc(25% - 空隙)。 - Banana
实现已更新。 - SW4

1

类似于已经发布的解决方案,但我认为这是唯一真正稳定可靠的解决方案。

JSFIDDLE DEMO

<div class="wrap">
    <div><img src="http://lorempixel.com/600/300/people/5/" style="display:block;"/></div>
    <div><img src="http://lorempixel.com/600/300/people/5/" style="display:block;"/></div>
    <div><img src="http://lorempixel.com/600/300/people/5/" style="display:block;"/></div>
</div>

.wrap
{
    display:table;
    width:100%;
    table-layout:fixed;
}

.wrap > div {
    display:table-cell;
    border:1px red solid;
    overflow:hidden;
    height:100px;
    transition:width 1s;
    width:33.333%;
}

.wrap > div:hover {
    width: 70%;
}

0

使用一个包装 div 怎么样:

<div class="wrapper">
  <div style="background-color: blue;"></div>
  <div style="background-color: red;"></div>
  <div style="background-color: green;"></div>
  <div style="background-color: purple;"></div>
</div>

然后在 CSS 中:

.wrapper div {
  width: 25%;
  height: 100px;
  float: left;
}
.wrapper:hover div {
  width: 12%;
}
.wrapper div:hover {
  width: 64%;
}
.wrapper {
    width: 100%;
}

JSFiddle: 这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接