【问题标题】:CSS child element to inherit background of parent's parent - iMessage in CSSCSS子元素继承父母的父母的背景 - CSS中的iMessage
【发布时间】:2015-10-23 10:21:20
【问题描述】:

一位客户要求我模拟 iMessage 聊天气泡,它在您滚动时具有淡化效果,即顶部气泡比底部气泡略浅的蓝色阴影。

我能想到的最简单的方法(不使用 javascript)是让基本背景具有渐变,然后顶部的子元素具有透明背景,因此当您滚动时,您会在子元素中获得渐变背景。这行得通,但事实证明,填充气泡周围的空白是一个真正的挑战。

基本上我想知道是否有一些神奇的 css 类可以让我在孩子身上应用一个忽略第一个父母背景并继承其下的背景的背景。

例如:

<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;
}

编辑:我们尝试用渐变类覆盖容器,但这会破坏滚动并且能够单击下面的按钮。

我们也尝试过边框、伪元素等,但调整大小通常会对此产生不利影响。

这是针对跨浏览器桌面和平板电脑的网站,因此必须具有一定的响应能力。

非常感谢,

山姆

【问题讨论】:

  • 你想要整个元素褪色,还是只有背景颜色?
  • 您好,如果您可以使用 iPhone,设计师实际上已经复制了 iMessage 的滚动效果。所以只是背景颜色会改变,文本将保持白色。例如,底部气泡为深蓝色,顶部气泡为浅蓝色。当您滚动时,它保持不变。气泡周围是静态颜色,例如白色。

标签: css imessage


【解决方案1】:

我能想到的最简单的方法(没有 javascript)是 使基础背景具有渐变,然后是子元素 顶部有透明背景..

  1. 如果您只满足于具有淡入淡出效果(即渐变),那么就反其道而行之。否则,您将陷入陷阱,然后在每个滚动条上识别当前顶部的气泡,然后更改样式。很快,这将成为您的噩梦。

将一个元素保持在顶部并为其赋予渐变,以便最顶部的气泡通过该元素通过透明度可见,从而在滚动时淡出。

最简单的方法是让您的标记如下:

<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));
}

这会将渐变放在聊天包装窗口的顶部,气泡将在其下方滚动到 container 内。

以下是从这个答案衍生的演示: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>

编辑

模拟 iMessage 聊天气泡,当您使用时会产生淡化效果 滚动,即顶部的气泡比蓝色略浅 底部气泡。

  1. 如果您希望准确地模拟 iMessage 的行为,那么您必须记住没有淡入淡出效果。顶部气泡的颜色与其余气泡不同(接近青色)。没有阴影或褪色。

为了做到这一点,您将不得不求助于 Javascript,因为 CSS 无法根据滚动来确定当前哪个气泡位于顶部。只需连接容器的scroll 事件,然后检查气泡的位置并相应地更改颜色。

以下是基于上述演示的纯 Javascript 示例(无 jQuery)。

演示小提琴: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>

这将解决您的聊天窗口顶部被遮挡的问题。这将允许从顶部进行触摸滚动,并且不会阻碍气泡上的交互。

【讨论】:

  • 您好,谢谢您的回复。我们也想到并尝试了这个解决方案。它的问题在于渐变层位于容器层的顶部,您无法单击该区域(有时我们有按钮),并且如果您尝试滚动该区域,则它不允许滚动等. 使用他们想要的渐变,它可能必须覆盖高度的 2/3,所以它不是真正可行的。我们现在走的是 js 路线,并且会随着我们的发展而发挥性能。我将编辑问题。再次感谢
  • @sam9046:我同意触摸滚动将是一个问题,而且如果您与气泡有交互,那么这也是一个问题。我已经更新了答案以添加一个简单的基于 Javascript 的解决方案。但如果有很多泡沫,性能可能会受到影响。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-13
相关资源
最近更新 更多