【问题标题】:How to implement Read more / Read less in pure CSS如何在纯 CSS 中实现 Read more / Read less
【发布时间】:2020-01-15 16:40:01
【问题描述】:

我正在以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 实用程序有冲突的地方,请告诉我。

【问题讨论】:

  • 您正在使用同级选择器,CSS 在选择元素时无法向上遍历 DOM。将inputlabel 移动到div 上方。
  • 谢谢@Harry,我会在修复后回帖。
  • 好的,虽然这是有道理的@Harry,“阅读更多”/“阅读更少”控制链接 [now] 显示在内容上方而不是内容中。不知道为什么它适用于 Codepen 作者而不是我的文档流。
  • &lt;input&gt; 放在&lt;div&gt; 之前,以便您可以使用兄弟选择器。将&lt;label&gt; 放在&lt;div&gt; 之后,使其显示在内容下方。
  • Put the &lt;input&gt; before the &lt;div&gt; so that you can use the sibling selector. Put the &lt;label&gt; after the &lt;div&gt; so it appears below the content. 我从 @DarkFalcon 开始,显示更多内容不可点击。立即查看该页面。

标签: css css-selectors toggle


【解决方案1】:

CodePen 如何实现这种行为?

演示中的代码所做的只是根据选中或未选中的复选框修改包装器divmax-height,同时更改label 的内容。

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

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

  • 这个选择器意味着当一个带有class = 'read-more-state'input被选中时,选择带有class = 'read-more-target'的元素,这些元素存在于带有class = 'read-more-wrap'的包装器下,当包装器也是复选框的兄弟时(参考元素)。

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

  • 这是填充label 的默认文本的那个。它的作用是将content 设置为labelclass = 'read-more-trigger'::before 元素的“显示更多”,而label 也是复选框的兄弟。李>

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

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

另外,请注意label 标记中的for 属性。该字段的值指向input 标记的id,因此无论何时单击标签,input 元素的状态都会自动切换。无论labelinput 元素在DOM 中的哪个位置,都会发生这种情况。

.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 选择器只能在 DOM 中的引用元素之后/下方出现同级元素时才能选择它。在您的 sn-p 中,需要选择的 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;
}
<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。这样做意味着参考元素现在位于需要选择和设置样式的元素之上。因此,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>

【讨论】:

  • 很好@Harry。我会通读;消化;测试;并很快回复。非常感谢您帮助我解决问题。我喜欢这个 RM/RL 功能,并希望它可以在我的网站上运行,这样我以后也可以重复使用它。
  • 对不起@Harry,但我对此很愚蠢。我只是不明白。你的答案、你的代码 sn-p 和你的小提琴与我的网络文档有什么不同?一切正常,但我的网络文档与您缩小的 sn-ps 相同。
  • SO IS MINE -- 这是多么令人沮丧 `width="270">

    Rob`

  • 没错。我只是不知道冲突在哪里/是什么。这就是我发帖的原因。
  • 哦,你太棒了@Harry...这很有效!非常非常非常非常感谢。我花了好几个小时在这件事上苦苦挣扎。
猜你喜欢
相关资源
最近更新 更多
热门标签