如何在纯 CSS 中实施多读/少读
How to implement Read more / Read less in pure CSS
我正在使用 http://codepen.io/Idered/pen/AeBgF 作为起点实施 CSS 多读/少读功能。
我修改了它以处理 <p>
标签与 <li>
列表项。
的页面上使用代码
这是我的 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 是如何实现这种行为的?
演示中的所有代码都是根据选中或未选中的复选框修改包装器 div
的 max-height
,同时更改 div
的内容=18=]。
现在让我们来看看 select 中帮助执行此操作的关键人物 select:
.read-more-state:checked ~ .read-more-wrap .read-more-target
- 这 selector 意味着当检查
input
和 class = '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表示当input
和class = 'read-more-state'
为:checked
时,将label的before元素的content
设置为"Show less".
另外,请注意 label
标记中的 for
属性。此字段的值指向 input
标签的 id
,因此只要单击标签,input
元素的状态就会自动切换。无论 DOM 中 label
和 input
元素位于何处,这都会发生。
.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>
我正在使用 http://codepen.io/Idered/pen/AeBgF 作为起点实施 CSS 多读/少读功能。
我修改了它以处理 <p>
标签与 <li>
列表项。
这是我的 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 是如何实现这种行为的?
演示中的所有代码都是根据选中或未选中的复选框修改包装器 div
的 max-height
,同时更改 div
的内容=18=]。
现在让我们来看看 select 中帮助执行此操作的关键人物 select:
.read-more-state:checked ~ .read-more-wrap .read-more-target
- 这 selector 意味着当检查
input
和class = '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表示当input
和class = 'read-more-state'
为:checked
时,将label的before元素的content
设置为"Show less".
另外,请注意 label
标记中的 for
属性。此字段的值指向 input
标签的 id
,因此只要单击标签,input
元素的状态就会自动切换。无论 DOM 中 label
和 input
元素位于何处,这都会发生。
.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>