如何在纯CSS中实现Read more/Read less

H. *_*nce 2 css toggle css-selectors css3

我正在使用http://codepen.io/Idered/pen/AeBgF作为起点实现CSS读取更多/读取更少的功能.

我修改了它来处理<p>标签与<li>列表项.

我无法在http://bit.ly/1L5vMm7上找到我的页面上的代码

这是我的CSS版本:

input.read-more-state {
    display: none;
}

p.read-more-target {
    font-size: 0;
    max-height: 0;
    opacity: 0;
    transition: .25s ease;
}

input.read-more-state:checked ~ div.read-more-wrap p.read-more-target {
    font-size: inherit;
    max-height: 999em;
    opacity: 1;
}

input.read-more-state ~ label.read-more-trigger:before {
    content: 'Read more';
}

input.read-more-state:checked ~ label.read-more-trigger:before {
    content: 'Read less';
}

label.read-more-trigger {
    cursor: pointer;
    display: inline-block;
}
Run Code Online (Sandbox Code Playgroud)

这是我的HTML:

<input class="read-more-state" id="read-more-controller" type="checkbox">
<div class="read-more-wrap">
    <p>Lorem ipsum dolor sit amet...</p>
    <p class="read-more-target">Lorem ipsum dolor sit amet...</p>
    <p class="read-more-target">Lorem ipsum dolor sit amet...</p>
    <p class="read-more-target">Lorem ipsum dolor sit amet...</p>
</div>
<label class="read-more-trigger" for="read-more-controller"></label>
Run Code Online (Sandbox Code Playgroud)

如果您能发现与RM/RL实用程序冲突的内容,请告诉我.

Har*_*rry 7

CodePen如何实现此行为?

演示中的代码所做的就是根据被选中或未选中的复选框修改max-height包装器div,同时这样做也会更改内容label.

现在让我们看一下CSS中用于帮助执行此操作的关键单个选择器:

.read-more-state:checked ~ .read-more-wrap .read-more-target

  • 这个选择意味着当inputclass = 'read-more-state'被检查,选择与所述元件class = 'read-more-target',其是一个包装下存在与class = 'read-more-wrap'当包装也是该复选框(参考元件)的兄弟节点.

.read-more-state ~ .read-more-trigger:before

  • 这是填充默认文本的那个label.当它也是复选框的兄弟时,它的作用是为with 的元素设置content"显示更多".::beforelabelclass = 'read-more-trigger'label

.read-more-state:checked ~ .read-more-trigger:before

  • 这是修改label单击复选框时的文本的那个.选择器意味着当inputwith class = 'read-more-state'为时:checked,将content元素前面的标签设置为"Show less".

另外,请注意标记中的for属性label.该字段的值指向id了的input标签,因此只要点击标签时,input元素的状态就会自动切换.无论DOM labelinput元素在哪里,都会发生这种情况.

.read-more-state {
  display: none;
}
.read-more-target {
  opacity: 0;
  max-height: 0;
  font-size: 0;
  transition: .25s ease;
}
.read-more-state:checked ~ .read-more-wrap .read-more-target {
  opacity: 1;
  font-size: inherit;
  max-height: 999em;
}
.read-more-state ~ .read-more-trigger:before {
  content: 'Show more';
}
.read-more-state:checked ~ .read-more-trigger:before {
  content: 'Show less';
}
.read-more-trigger {
  cursor: pointer;
  display: inline-block;
  padding: 0 .5em;
  color: #666;
  font-size: .9em;
  line-height: 2;
  border: 1px solid #ddd;
  border-radius: .25em;
}
/* Other style */

body {
  padding: 2%;
}
p {
  padding: 2%;
  background: #fff9c6;
  color: #c7b27e;
  border: 1px solid #fce29f;
  border-radius: .25em;
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <input type="checkbox" class="read-more-state" id="post-1" />

  <p class="read-more-wrap">Lorem ipsum dolor sit amet, consectetur adipisicing elit. <span class="read-more-target">Libero fuga facilis vel consectetur quos sapiente deleniti eveniet dolores tempore eos deserunt officia quis ab? Excepturi vero tempore minus beatae voluptatem!</span>
  </p>

  <label for="post-1" class="read-more-trigger"></label>
</div>

<div>
  <input type="checkbox" class="read-more-state" id="post-2" />

  <ul class="read-more-wrap">
    <li>lorem</li>
    <li>lorem 2</li>
    <li class="read-more-target">lorem 3</li>
    <li class="read-more-target">lorem 4</li>
  </ul>

  <label for="post-2" class="read-more-trigger"></label>
</div>
Run Code Online (Sandbox Code Playgroud)


为什么我的代码不起作用?

CSS选择器只有在DOM中的引用元素之后/之下存在时才能选择兄弟元素.在您的代码段中,div需要选择的内容出现在input(它是引用元素并且其状态触发操作)之后,因此CSS无法选择它.没有选择导致不应用属性更改.

input.read-more-state {
  display: none;
}
p.read-more-target {
  font-size: 0;
  max-height: 0;
  opacity: 0;
  transition: .25s ease;
}
input.read-more-state:checked ~ div.read-more-wrap p.read-more-target {
  font-size: inherit;
  max-height: 999em;
  opacity: 1;
}
input.read-more-state ~ label.read-more-trigger:before {
  content: 'Read more';
}
input.read-more-state:checked ~ label.read-more-trigger:before {
  content: 'Read less';
}
label.read-more-trigger {
  cursor: pointer;
  display: inline-block;
}
Run Code Online (Sandbox Code Playgroud)
<div class="read-more-wrap">
  <p>Lorem ipsum dolor sit amet...</p>
  <p class="read-more-target">Lorem ipsum dolor sit amet...</p>
  <p class="read-more-target">Lorem ipsum dolor sit amet...</p>
  <p class="read-more-target">Lorem ipsum dolor sit amet...</p>
</div>
<input class="read-more-state" id="read-more-controller" type="checkbox">
<label class="read-more-trigger" for="read-more-controller"></label>
Run Code Online (Sandbox Code Playgroud)


我怎么解决这个问题?

只需将input标记移动到包装div标签上方,max-height当单击标签时需要更改标签.这样做意味着引用元素现在位于需要选择和设置样式的元素之上.因此,CSS将能够max-height正确应用并揭示隐藏的内容.

input.read-more-state {
  display: none;
}
p.read-more-target {
  font-size: 0;
  max-height: 0;
  opacity: 0;
  transition: .25s ease;
}
input.read-more-state:checked ~ div.read-more-wrap p.read-more-target {
  font-size: inherit;
  max-height: 999em;
  opacity: 1;
}
input.read-more-state ~ label.read-more-trigger:before {
  content: 'Read more';
}
input.read-more-state:checked ~ label.read-more-trigger:before {
  content: 'Read less';
}
label.read-more-trigger {
  cursor: pointer;
  display: inline-block;
}
Run Code Online (Sandbox Code Playgroud)
<input class="read-more-state" id="read-more-controller" type="checkbox">
<div class="read-more-wrap">
  <p>Lorem ipsum dolor sit amet...</p>
  <p class="read-more-target">Lorem ipsum dolor sit amet...</p>
  <p class="read-more-target">Lorem ipsum dolor sit amet...</p>
  <p class="read-more-target">Lorem ipsum dolor sit amet...</p>
</div>
<label class="read-more-trigger" for="read-more-controller"></label>
Run Code Online (Sandbox Code Playgroud)