如何实现在纯CSS中阅读更多/更少 [英] How to implement Read more / Read less in pure CSS
问题描述
我正在使用 http://codepen.io/Idered/ pen / AeBgF 作为起点。
我将其修改为工作< 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-stateid =read-more-controllertype =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-triggerfor =read-more-controller>< / label>
让我知道如果你能发现什么是与RM / RL实用程序冲突。
CodePen如何实现此行为?
所有演示程序中的代码都是根据检查的结果修改包装器 div
的 max-height
框被选中或取消选中,同时还会更改标签
的内容。
现在让我们来看一下CSS中的关键个别选择器,帮助执行此操作:
.read-more-state:checked〜.read-more-wrap .read-more-target
- 此选择器表示当选中
class ='read-more-state'
的输入
包含class ='read-more-wrap'$的包装器中的
class ='read-more-target'
c $ c>当包装器也是复选框(引用元素)的兄弟元素时。
。 read-more-state〜.read-more-trigger:before
-
标签
的默认文本。它所做的是将:: before
之前的content
设置为显示更多当标签时,
标签 code>也是复选框的同级。
.read-more-state:checked 〜.read-more-trigger:before
- 这是修改< c $ c> label 。选择器意味着当
输入
与class ='read-more-state'
为:checked
,将显示较少之前的标签的content
设置为
此外,请注意标签
中 c>标记。此字段的值指向
输入
标签的 id
,因此每当标签被点击时, input
元素的状态会自动切换。不管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;颜色:#666; font-size:.9em; line-height:2; border:1px solid #ddd; border-radius:.25em;} / *其他样式* / body {padding:2%;} p {padding:2%;背景:#fff9c6;颜色:#c7b27e; border:1px solid#fce29f; border-radius:.25em;}
< div& < input type =checkboxclass =read-more-stateid =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 quo sapiente deleniti eveniet dolores tempore eos deserunt officia quis ab? < / span>< / span> < / p> < label for =post-1class =read-more-trigger>< / label>< / div>< div& < input type =checkboxclass =read-more-stateid =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-2class =read-more-trigger>< / label>< / div>
/ div>
为什么我的代码无效?
CSS选择器只能在DOM中的引用元素之后/下面存在的情况下选择一个兄弟元素。在你的代码片段中,需要选择的
div
在输入
(它是引用元素,状态触发动作),因此CSS无法选择它。没有选择结果不会应用属性更改。
input.read-more-state {display:none;} p .read-more-target {font-size:0; max-height:0;不透明度: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-stateid =read-more -controllertype =checkbox>< label class =read-more-triggerfor =read-more-controller>< / label>
如何解决这个问题?
只需将
输入
标签移到包装器之上div
标签,当max-height
需要在单击标签时更改。这样做意味着引用元素现在位于需要选择和样式化的元素之上。因此,CSS将能够正确应用max-height
并显示隐藏的内容。
input.read-more-state {display:none;} p.read-more-target {font-size:0; max-height:0;不透明度: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-stateid =read-more-controllertype =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-triggerfor =read-more -controller>< / label>
I am implementing a CSS read more / read less capability using http://codepen.io/Idered/pen/AeBgF as a starting point.
I modified it to work off
<p>
tags vs.<li>
list items.I can't get the code to work on my page at http://bit.ly/1L5vMm7
Here is my version of the 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; }
Here is my 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>
Let me know if you can discover what is conflicting with the RM/RL utility.
解决方案How does the CodePen achieve this behavior?
All that the code in the demo does is modify the
max-height
of the wrapperdiv
based on the check-box being checked or unchecked and whilst doing so also change the content of thelabel
.Now lets have a look at the key individual selectors in CSS that help perform this:
.read-more-state:checked ~ .read-more-wrap .read-more-target
- This selector means that when an
input
withclass = 'read-more-state'
is checked, select the elements withclass = 'read-more-target'
which are present under a wrapper withclass = 'read-more-wrap'
when the wrapper is also a sibling of the checkbox (the reference element).
.read-more-state ~ .read-more-trigger:before
- This is the one that populates the default text for the
label
. What it does is set thecontent
as "Show more" for the::before
element oflabel
withclass = 'read-more-trigger'
when thelabel
is also a sibling of the checkbox.
.read-more-state:checked ~ .read-more-trigger:before
- This is the one that modifies the text of the
label
when the checkbox is clicked. The selector means that when theinput
withclass = 'read-more-state'
is:checked
, set thecontent
of the label's before element as "Show less".
Also, note the for
attribute in the label
tag. The value of this field points to the id
of the input
tag and so whenever the label is clicked, the input
element's state gets toggled automatically. This will happen irrespective of where in DOM the label
and input
elements are.
.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>
Why does my code not work?
CSS selectors can select a sibling element only when it is present after/below the reference element in the DOM. In your snippet, the div
which needs to be selected is present after the input
(which is the reference element and whose state triggers the action) and hence CSS is not able to select it. No selection results in no property change being applied.
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>
How can I solve this problem?
Just move the input
tag to be above the wrapper div
tag whose max-height
needs to be changed when the label is clicked. Doing this would mean that the reference element is now above the element that needs to be selected and styled. Thus, CSS would be able to apply the max-height
properly and reveal the hidden contents.
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>
这篇关于如何实现在纯CSS中阅读更多/更少的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!