我有blockquote
这样:
<blockquote class="spoiler">Soopah sekkrit!</blockquote>
我想隐藏它,只有当用户将鼠标悬停在它上面时才显示它。我现在正在使用JS:
blockquote.addEventListener('mouseover', function() {
this.style.height = this.offsetHeight + 'px';
this.dataset.contents = this.innerHTML;
this.innerHTML = '';
});
blockquote.addEventListener('mouseout', function() {
this.style.height = '';
this.innerHTML = this.dataset.contents;
});
使用CSS有没有更好的方法呢?
它必须保持其background-color
,大小和内容的自定义颜色。如果可能的话,我也想制作它的动画,以便内容逐渐淡出。
答案 0 :(得分:14)
这与我在SOUP中使用的内容非常相似:
.spoiler, .spoiler > * { transition: color 0.5s, opacity 0.5s }
.spoiler:not(:hover) { color: transparent }
.spoiler:not(:hover) > * { opacity: 0 }
/* fix weird transitions on Chrome: */
blockquote, blockquote > *:not(a) { color: black }
.spoiler, .spoiler > * { transition: color 0.5s, opacity 0.5s }
.spoiler:not(:hover) { color: transparent }
.spoiler:not(:hover) > * { opacity: 0 }
/* fix weird transitions on Chrome: */
blockquote, blockquote > *:not(a) { color: black }
/* some basic bg styles for demonstration purposes */
blockquote { background: #fed; margin: 1em 0; padding: 8px; border-left: 2px solid #cba }
code { background: #ccc; padding: 2px }
img { vertical-align: middle }
<blockquote class="spoiler">
Soopah sekkrit text with <code>code</code> and <a href="#">links</a> and <img src="//sstatic.net/stackexchange/img/logos/so/so-logo-med.png" width="100" /> images!
<p>You can also have paragraphs in here.</p>
<ul><li>And lists too!</li></ul>
<blockquote class="spoiler">Even nested spoilers work!</blockquote>
</blockquote>
这比your own solution稍微简单,适用于任意内容,包括图像甚至嵌套剧透! (参见上面的演示片段。)
唉,如果扰流板的任何子元素都有color: inherit
,这种方法似乎会受到Chrome上奇怪的过渡效果的影响。 (基本上,正在发生的是这些元素将两者将其文本颜色设置为透明,并将其不透明度设置为0.因为不透明度会成倍增加,因此组合过渡将显得更慢 - 在淡入淡出的中途 - 在,当元素本身的不透明度为50%时,其中的文本为50%×50%= 25%不透明度。)我在上面的示例中添加了一个额外的CSS规则来修复这,但它确实使事情变得有点复杂。
我在SOUP中实际做的事情略有不同。我将每个剧透的内容包装在一个额外的内部<div>
中,这让我可以进一步简化CSS:
.spoiler > div { opacity: 0; transition: opacity 0.5s }
.spoiler:hover > div { opacity: 1 }
.spoiler > div { opacity: 0; transition: opacity 0.5s }
.spoiler:hover > div { opacity: 1 }
/* some basic bg styles for demonstration purposes */
blockquote { background: #fed; margin: 1em 0; padding: 8px; border-left: 2px solid #cba }
code { background: #ccc; padding: 2px }
img { vertical-align: middle }
<blockquote class="spoiler"><div>
Soopah sekkrit text with <code>code</code> and <a href="#">links</a> and <img src="//sstatic.net/stackexchange/img/logos/so/so-logo-med.png" width="100" /> images!
<p>You can also have paragraphs in here.</p>
<ul><li>And lists too!</li></ul>
<blockquote class="spoiler"><div>Even nested spoilers work!</div></blockquote>
<div></blockquote>
此方法的主要优点是简单性和健壮性:我不必使用:not()
选择器,提高与旧浏览器的兼容性,transition
样式不能与其他转换冲突在剧透内部的内部上定义。此方法也不会受到上述Chrome上的颜色过渡怪异的影响,因为它只使用不透明度过渡。
总的来说,这是我推荐的方法。当然,缺点是您需要在HTML中包含额外的<div>
。
Ps。请考虑提供一些方法使剧透图永久可见,尤其是对于可能发现很难将光标“悬停”在元素上的触摸屏用户。一个简单的解决方案是使用JavaScript单击事件处理程序来切换spoiler
类,例如像这样(使用jQuery):
$('.spoiler').on( 'click', function (e) {
$(this).toggleClass('spoiler');
e.stopPropagation();
} );
$('.spoiler').on( 'click', function (e) {
$(this).toggleClass('spoiler');
e.stopPropagation();
} );
.spoiler > div { opacity: 0; transition: opacity 0.5s }
.spoiler:hover > div { opacity: 1 }
/* some basic bg styles for demonstration purposes */
blockquote { background: #fed; margin: 1em 0; padding: 8px; border-left: 2px solid #cba }
code { background: #ccc; padding: 2px }
img { vertical-align: middle }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<blockquote class="spoiler"><div>
Soopah sekkrit text with <code>code</code> and <a href="#">links</a> and <img src="//sstatic.net/stackexchange/img/logos/so/so-logo-med.png" width="100" /> images!
<p>You can also have paragraphs in here.</p>
<ul><li>And lists too!</li></ul>
<blockquote class="spoiler"><div>Even <a href="//example.com">nested</a> spoilers work!</div></blockquote>
<div></blockquote>
或者,如果您更喜欢使用委托事件处理(这样您每次通过Ajax加载包含剧透的新内容时都不必继续添加新的点击处理程序):
$(document).on( 'click', '.spoiler, .spoiler-off', function (e) {
$(this).toggleClass('spoiler').toggleClass('spoiler-off');
e.stopPropagation();
} );
$(document).on( 'click', '.spoiler, .spoiler-off', function (e) {
$(this).toggleClass('spoiler').toggleClass('spoiler-off');
e.stopPropagation();
} );
.spoiler > div { opacity: 0; transition: opacity 0.5s }
.spoiler:hover > div { opacity: 1 }
/* some basic bg styles for demonstration purposes */
blockquote { background: #fed; margin: 1em 0; padding: 8px; border-left: 2px solid #cba }
code { background: #ccc; padding: 2px }
img { vertical-align: middle }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<blockquote class="spoiler"><div>
Soopah sekkrit text with <code>code</code> and <a href="#">links</a> and <img src="//sstatic.net/stackexchange/img/logos/so/so-logo-med.png" width="100" /> images!
<p>You can also have paragraphs in here.</p>
<ul><li>And lists too!</li></ul>
<blockquote class="spoiler"><div>Even <a href="//example.com">nested</a> spoilers work!</div></blockquote>
<div></blockquote>
(这些应该适用于上面显示的任何CSS变体。)
答案 1 :(得分:11)
是的,这可以通过CSS实现。基本上,您希望使所有内容都不可见。在CSS中,这意味着透明。
首先使用hover pseudo-class中的not pseudo-class:
.spoiler:not(:hover)
但我们还需要选择悬停扰流板的所有子元素,设置它们的颜色和背景:
.spoiler:not(:hover) *
我们将颜色和背景(仅适用于子元素)设置为transparent
,以使其对用户不可见。一起来:
.spoiler:not(:hover), .spoiler:not(:hover) * { color: transparent }
.spoiler:not(:hover) * { background: transparent }
code { padding: 2px; background: #bbb }
a { color: #00f }
Hover: <blockquote class="spoiler">Some stuff <a>and a colored link</a> <code>and some code!</code></blockquote>
我们还可以添加transition
以使其更顺畅:
.spoiler { transition: color 0.5s } /* we have to put this outside the :hover to make it work fading both in and out */
.spoiler:not(:hover), .spoiler:not(:hover) * { color: transparent }
.spoiler * { transition: color 0.5s, background 0.5s }
.spoiler:not(:hover) * { background: transparent }
code { padding: 2px; background: #bbb; color: #000 } /* add color to prevent double transition */
a { color: #00f }
Hover: <blockquote class="spoiler">Some stuff <a>and a colored link</a> <code>and some code!</code></blockquote>
为了让用户明白blockquote是可以缓存的,你可以添加一些::after
pseudo-element的文本,以便在没有悬停块引用时显示:
.spoiler { transition: color 0.5s; position: relative } /* relative position for positioning the pseudo-element */
.spoiler:not(:hover), .spoiler:not(:hover) * { color: transparent }
.spoiler * { transition: color 0.5s, background 0.5s }
.spoiler:not(:hover) * { background: transparent }
.spoiler::after {
content: 'hover to view spoiler';
position: absolute;
top: 0; left: 0;
color: transparent;
}
.spoiler:not(:hover)::after {
color: #666;
transition: color 0.3s 0.3s; /* delayed transition to keep the text from overlapping */
}
code { padding: 2px; background: #bbb; color: #000 }
a { color: #00f }
<blockquote class="spoiler">
Some stuff <a>and a colored link</a> <code>and some code!</code>
<blockquote class="spoiler">Nesting bonus!</blockquote>
</blockquote>
对于像图像,svgs(内联SVG可以非常精细控制),画布和所有那些花哨的东西,而不是color
,你必须使用opacity
。我们可以通过添加以下内容使其成功:
.spoiler img { transition: opacity 0.5s, background 0.5s }
.spoiler:not(:hover) img { opacity: 0 }
答案 2 :(得分:0)
这是一种效果很好,看起来不错并且过渡非常干净的策略
CompletableFuture
如果您使用MainThread
为父块设置样式而不设置鼠标悬停,则无法添加任何样式来说明用户应将鼠标悬停在页面的哪一部分。
相反,如果我们添加一个.spoiler {
position: relative;
display: inline-block;
cursor: help;
}
.spoiler::before {
content: 'psst\02026'; /* … */
position: absolute;
left: -2px;
top: -2px;
right: -2px;
bottom: -2px;
border-radius: 1px;
font-size: .9rem;
color: #e6578c;
background: #ffe5e5;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
opacity: 1;
transition: opacity 0.7s ease, transform 0.3s ease; /* hide faster than reveal */
}
.spoiler:hover::before {
opacity: 0;
transform: translateY(-50%)rotateX(80deg);
transition: opacity 1.0s ease, transform 0.5s ease; /* slower reveal */
}
元素来掩盖子内容,那么我们可以在悬停时淡出它,并仍然提供视觉指示。
opacity: 0
::before