如何在纯 CSS 中实施多读/少读

How to implement Read more / Read less in pure CSS

我正在使用 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;
}

这是我的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>

如果您能发现什么与 RM/RL 实用程序冲突,请告诉我。

CodePen 是如何实现这种行为的?

演示中的所有代码都是根据选中或未选中的复选框修改包装器 divmax-height,同时更改 div 的内容=18=]。

现在让我们来看看 select 中帮助执行此操作的关键人物 select:

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

  • 这 selector 意味着当检查 inputclass = 'read-more-state' 时,select 带有 class = 'read-more-target' 的元素出现在包装器下class = 'read-more-wrap' 当包装器也是复选框(引用元素)的兄弟时。

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

  • 这是填充 label 的默认文本的文本。它所做的是将 content 设置为 "Show more" 用于 label::before 元素和 class = 'read-more-trigger'label 也是复选框的兄弟。

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

  • 这是在单击复选框时修改 label 文本的那个。 selector表示当inputclass = 'read-more-state':checked时,将label的before元素的content设置为"Show less".

另外,请注意 label 标记中的 for 属性。此字段的值指向 input 标签的 id,因此只要单击标签,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;
}
<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>


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

CSS select 或者可以 select 兄弟元素只有当它存在时 after/below DOM 中的引用元素。在您的代码段中,需要 selected 的 div 出现在 input 之后(这是参考元素,其状态触发操作),因此 CSS 是无法 select 它。没有 selection 导致没有应用 属性 变化。

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;
}
<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>


如何解决这个问题?

只需将 input 标签移动到包装 div 标签上方,单击标签时需要更改 max-height 标签。这样做意味着引用元素现在位于需要 select 编辑和设置样式的元素之上。因此,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;
}
<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>