一位客户要求我模拟 iMessage 聊天气泡,当您滚动时它会产生淡入淡出的效果,即顶部气泡的蓝色阴影比底部气泡稍微浅一些。
我能想到的最简单的方法(没有 javascript)是让基本背景具有渐变,然后顶部的子元素具有透明背景,这样当您滚动时,您会在子元素中获得渐变背景。这可行,但填充气泡周围的空白已被证明是一个真正的挑战。
基本上我想知道是否有一些神奇的 css 类可以让我在 child 上应用一个背景,忽略第一个 parent 的背景并继承下面的背景。
例如:
<div class="gradient">
<div class="container">
<div class="child">
I'm a bubble
</div>
</div>
</div>
.gradient {
height: 500px;
background: -webkit-linear-gradient(top, #7db9e8 0%,#1e5799 100%);
}
.container {
height: 500px;
/* I want this background to be around the child */
background: white;
position: relative;
}
.child {
position: relative;
top: 100px;
left: 50%;
height: 50px;
width: 100px;
/* I want the gradient background here NOT the container background */
background: transparent;
border: 1px solid black;
}
编辑:我们已经尝试用渐变类覆盖容器,但这会破坏滚动并能够单击下面的按钮。
我们也尝试过边框、伪元素等,但调整大小通常会对此产生不利影响。
这是针对跨浏览器的桌面和平板电脑站点,因此必须具有一定的响应能力。
非常感谢,
山姆
最佳答案
The simplest way I could think of doing this (without javascript) was for a base background to have a gradient, and then the child elements on top have a transparent background..
- 如果您对淡入淡出效果(即渐变)感到满意,那么就反过来做吧。否则你将陷入陷阱,然后在每个滚动条上识别当前顶部的气泡,然后更改样式。很快这将成为您的噩梦。
将一个元素保留在顶部并为其设置渐变,以便通过透明度通过该元素可以看到最顶部的气泡,从而在滚动时淡出。
最简单的方法是使用这样的标记:
<div class="wrap"> <!-- The outermost wrapper for entire chat -->
<div class="container"> <!-- The chat window container -->
<div class="bubble"><p>msg</p></div> <!-- individual chat bubbles -->
</div>
</div>
然后通过 CSS 在它上面放置一个元素:
.wrap::after {
content: ''; position: relative; display: block;
top: -100%; left: 0;
width: calc(100% - 16px); height: 64px;
background-image: linear-gradient(rgba(0,0,0,1), rgba(0,0,0,0));
}
这会将渐变放在聊天包装窗口的顶部,气泡将在 容器
内滚动到它下面。
下面是从这个答案派生的演示:https://stackoverflow.com/a/27486767/1355315
演示片段 1:
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
.wrap { margin: 8px; height: 80%; width: 50%; overflow: hidden; }
.container {
background-color: #eee;
height: 100%; width: 100%;
overflow: auto;
}
.bubble { width: 100%; clear: both; } /* clear the floats here on parent */
.bubble p {
border-radius: 5px;
padding: 8px; margin: 8px 12px;
max-width: 80%; /* this will make it not exceed 80% and then wrap */
position: relative;
}
.left p { background-color: #ccc; float: left; } /* floated left */
.right p { background-color: #33c; color: #fff; float: right; } /* floated right */
/* classes below are only for arrows, not relevant */
.left p::before {
content: ''; position: absolute;
width: 0; height: 0; left: -8px; top: 8px;
border-top: 4px solid transparent;
border-right: 8px solid #ccc;
border-bottom: 4px solid transparent;
}
.right p::after {
content: ''; position: absolute;
width: 0; height: 0; right: -8px; bottom: 8px;
border-top: 4px solid transparent;
border-left: 8px solid #33c;
border-bottom: 4px solid transparent;
}
.wrap::after {
content: ''; position: relative;
top: -100%; left: 0;
display: block; width: calc(100% - 16px); height: 64px;
background-image: linear-gradient(rgba(242,242,242,1), rgba(242,242,242,0));
}
<div class="wrap">
<div class="container">
<div class="bubble left"><p>msg</p></div>
<div class="bubble left"><p>long message</p></div>
<div class="bubble right"><p>ultra long message which can wrap at eighty percent </p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>very long message</p></div>
<div class="bubble right"><p>one more message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>another message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>yet another message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
</div>
</div>
编辑
emulate the iMessage chat bubbles, which have a fade effect as you scroll, i.e. the top bubble is a slightly lighter shade of blue than the bottom bubble.
- 如果您希望准确模拟 iMessage 的行为,则必须记住没有淡入淡出效果。顶部气泡的颜色(接近青色)与其余气泡不同。没有阴影或褪色。
为此,您将不得不求助于 Javascript,因为 CSS 无法根据滚动确定当前哪个气泡位于顶部。只需连接容器的 scroll
事件,检查气泡的位置并相应地更改颜色。
下面是一个基于上述演示的纯 Javascript 示例(没有 jQuery)。
演示 fiddle :http://jsfiddle.net/abhitalks/oop2dazy/1/
演示片段 2:
var cw = document.getElementById('chatWindow'),
threshold = 64;
cw.addEventListener('scroll', function(e) {
var bubbles = cw.getElementsByClassName('right');
[].forEach.call(bubbles, function(elem) {
var top = elem.getBoundingClientRect().top
if (top < threshold) { elem.classList.add('faded'); }
else { elem.classList.remove('faded');}
});
});
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
.wrap { margin: 8px; height: 80%; width: 50%; overflow: hidden; }
.container {
background-color: #eee;
height: 100%; width: 100%;
overflow: auto;
}
.bubble { width: 100%; clear: both; } /* clear the floats here on parent */
.bubble p {
border-radius: 5px;
padding: 8px; margin: 8px 12px;
max-width: 80%; /* this will make it not exceed 80% and then wrap */
position: relative; transition: background-color 0.5s;
}
.left p { background-color: #ccc; float: left; } /* floated left */
.right p { background-color: #33c; color: #fff; float: right; } /* floated right */
/* classes below are only for arrows, not relevant */
.left p::before {
content: ''; position: absolute;
width: 0; height: 0; left: -8px; top: 8px;
border-top: 4px solid transparent;
border-right: 8px solid #ccc;
border-bottom: 4px solid transparent;
}
.right p::after {
content: ''; position: absolute;
width: 0; height: 0; right: -8px; bottom: 8px;
border-top: 4px solid transparent;
border-left: 8px solid #33c;
border-bottom: 4px solid transparent;
}
.bubble.faded p { background-color: #39c; }
.bubble.faded p::after { border-left: 8px solid #39c; }
<div class="wrap">
<div id="chatWindow" class="container">
<div class="bubble left"><p>msg</p></div>
<div class="bubble left"><p>long message</p></div>
<div class="bubble right"><p>ultra long message which can wrap at eighty percent </p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>very long message</p></div>
<div class="bubble right"><p>one more message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>another message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>yet another message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
</div>
</div>
这将解决聊天窗口顶部被遮挡的问题。这将允许从顶部进行触摸滚动,并且不会阻碍气泡上的交互。
关于CSS 子元素继承父级父级的背景 - CSS 中的 iMessage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33300070/