54

一行CSS实现滚动时藏在信息流后面的广告效果

 5 years ago
source link: https://www.zhangxinxu.com/wordpress/2018/07/css-information-stream-advertisement/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

这篇文章发布于 2018年07月14日,星期六,23:55,归类于css相关。 阅读 75 次, 今日 75 次

byzhangxinxu from https://www.zhangxinxu.com/wordpress/?p=7792

本文可全文转载,但需得到原作者书面许可,同时保留原作者和出处,摘要引流则随意。

一、看看是什么样子的广告交互效果

夏日炎炎,今天宅在家里刷微博的时候,刷到了个关于信息流广告的视频:

22MF323.png!web

究竟这个广告是个什么样子的呢,可以参见下面的视频:

这个广告其实还好啦,跟着滚和不跟着滚的区别嘛~不过,作为满脑子都是技术的瘦宅,第一反应就是:这个广告效果使用web前端技术该怎么实现?

几个idea试验了下,发现都可以实现类似的效果,一起来看看吧。

二、一行background-attachment:fixed搞定镂空信息流广告

这个方法理论上是最简单效果也最好的方法。

CSS中有个 background-attachment 属性,当我们设置属性值为 fixed 的时候,背景图片相对于窗体定位,不受滚动影响。

于是,我们的实现就很简单:信息流列表HTML中插入个广告 <a> 链接,然后广告图作为背景图呈现,设置 background-attachment:fixed 效果就可以实现了,就这么简单。

HTML和CSS代码示意:

<div class="list">信息流列表1</div>
<div class="list">信息流列表2</div>
<a href="#" class="ad" target="_blank">广告</a>
<div class="list">信息流列表3</div>
<div class="list">信息流列表4</div>
.ad {
    display: block;
    height: 600px;
    background: url(./ad.jpg) no-repeat top fixed;
    background-size: 100%;
}

眼见为实,您可以狠狠地点击这里: 基于backgroud实现的信息流广告demo

或者手机扫下面的码体验:

VnaAvqR.png!web

效果大致如下GIF截屏:

Bry6ZvF.jpg

唯一的不足:iOS Safari不支持background-attachment:fixed

iOS Safari很早时候 position:fixed 也不支持,后来妥协了,支持了;但是 background-attachment:fixed 还是老样子,不支持,怕是嫌弃 background-attachment:fixed 烧性能,对于一个连IE7,IE8浏览器都支持良好的CSS声明,Safari不支持(包括iOS微信),我也无力说些什么。

因此,我们还需要额外做些功夫,兼容下iPhone手机浏览器。

我的做法是如果是iPhone手机,广告图片 postion:fixed 定位,配合JS实时 clip 剪裁。核心JS如下:

// ele就是广告元素DOM对象
window.addEventListener('scroll', function () {
    var bound = ele.parentElement.getBoundingClientRect();
    var clip = 'rect('+ [bound.top + 'px', ele.parentElement.clientWidth + 'px', bound.bottom + 'px', 0].join() +')';
    ele.style.clip = clip;
});

三、position:fixed也可以实现藏在后面的信息流广告

position:fixed 也可以实现藏在后面的信息流广告,实现原理就是藏在其他信息流元素的背后,以及头部或者底部元素(如果有)的底部,关键就是 z-index 层级控制了。虽然原理简单,但是实际操作还是有些啰嗦的,通常信息流页面的HTML结构都比较复杂,此时再 z-index 属性各种设置,很容易造成 z-index 混乱。

我也花时间做了个demo,您可以狠狠地点击这里: position:fixed实现的信息流广告demo

或者手机扫下面的码体验:

vQjqQ3f.png!web

效果大致如下GIF截屏:

RBvEfq3.jpg

HTML和CSS代码原理示意:

<div class="list">信息流列表1</div>
<div class="list">信息流列表2</div>
<a href="#" class="ad" target="_blank">
   <img src="./ad.jpg">
</a>
<div class="list">信息流列表3</div>
<div class="list">信息流列表4</div>
.list {
    background-color: #fff;
    position: relative;
    z-index: 1;
}
.ad {
    display: block;
    height: 576px;
}
.ad img {
    position: fixed; top: 0;
    width: 400px;
}

优点和不足

基于 position:fixed 实现的优点在于:

1. 我们的广告内容可以支持复杂HTML,而不仅仅是一张图片;

2. 所有浏览器都兼容,包括iPhone Safari浏览器。

不足在于:

1. 需要其他元素进行层级配合,相互耦合增加了CSS的复杂度。

如果实际开发时候发现 z-index 层级控制比较麻烦,可以试试第一个demo中使用的CSS clip 剪裁,直接只显示当前广告区域内容,不过需要JS配合,不是纯CSS实现了,自己权衡。

四、结束语

采用 position:fixed 固定定位实现的时候,我们还可以把广告元素从信息流列表中抽离,直接放在整个容器的后面,然后借助 visibility 属性实现点击穿透,如下示意:

<a href="#" class="ad">广告</a>
<ul>
    <li>信息流列表1</li>
    <li>信息流列表2</li>
    <li></li> <!-- 撑开高度 -->
    <li>信息流列表3</li>
    <li>信息流列表4</li>
</ul>
.ad {
    position: fixed;
}
ul {
    position: relative;
    visibility: hidden;
}
li:empty {
    /* 撑开高度,实际开发请使用类名控制,这里精简HTML才使用:empty */
    height: 576px;
}
li:not(:empty) {
    visibility: visible;
}

具体就不展开了。

英格兰凉了,比利时很强。

希望本文内容可以帮助需要的人。

然后,如果你有更好地实现方法,欢迎不吝赐教!

u6vUrqR.png!web

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。

本文地址: https://www.zhangxinxu.com/wordpress/?p=7792

(本篇完)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK