overflow-anchorCSS中的属性相对较新,2017 年首次推出 Chrome ¹,2019 年推出 Firefox,现在 Edge在 2020 年推出 Chrome 过渡。幸运的是,它的使用在很大程度上是一种增强。这个想法是浏览器在默认情况下确实尝试不允许位置移动。然后,如果您不喜欢它的处理方式,您可以使用 将其关闭。所以一般来说,你从不碰它。overflow-anchor 但正如你可能怀疑的那样,我们可以利用这个小美来做一点 CSS 小把戏。即使我们添加新内容,我们也可以强制滚动元素保持固定在底部。

您需要检测何时使用 JavaScript 添加新内容并将滚动元素强制到底部。这是一种MutationObserver在 JavaScript 中使用的技术来监视新内容并强制滚动:

const scrollingElement = document.getElementById("scroller");const config = { childList: true };const callback = function (mutationsList, observer) {for (let mutation of mutationsList) {if (mutation.type === "childList") {window.scrollTo(0, document.body.scrollHeight);}}
};const observer = new MutationObserver(callback);
observer.observe(scrollingElement, config);

但我发现一个纯 CSS 的解决方案更有吸引力!上面的版本有一些我们稍后会介绍的用户体验缺陷。

这里的诀窍是浏览器默认已经做了滚动锚定。但是浏览器试图做的不是改变你的页面。因此,当添加可能会改变页面视觉位置的新内容时,他们会尝试防止这种情况发生。在这种不寻常的情况下,我们有点想要相反的东西。我们希望页面卡在页面底部并让视觉页面在视觉上移动,因为它被迫保持卡在底部。

下面是这个技巧的工作原理。首先是滚动父元素中的一些 HTML:

<div id="scroller"><!-- new content dynamically inserted here --><div id="anchor"></div>
</div>

所有元素自然都有一个overflow-anchor: auto;,这意味着当它们在屏幕上时,它们会试图阻止页面移动,但我们可以使用overflow-anchor: none;. 所以诀窍是针对所有动态插入的内容并将其关闭:

#scroller * {overflow-anchor: none;
}

然后仅强制该锚元素具有滚动锚定,仅此而已:

#anchor {overflow-anchor: auto;height: 1px;
}

现在,一旦该锚在页面上可见,浏览器将被迫将该滚动位置固定到它,并且由于它是该滚动元素中的最后一件事,因此保持固定在底部。

<div id="scroller"><!-- new content dynamically inserted here --><div id="anchor"></div>
</div><style>
#scroller * {overflow-anchor: none;
}#anchor {overflow-anchor: auto;height: 1px;
}html {font-family: system-ui, sans-serif;
}
body {background-color: #7FDBFF;/* In case you need to kick off effect immediately, this plus JS *//* height: 100.001vh; */
}.message {padding: 0.5em;border-radius: 1em;margin: 0.5em;line-height: 1.1em;background-color: white;
}
</style><script>
let scroller = document.querySelector('#scroller');
let anchor = document.querySelector('#anchor');// https://ajaydsouza.com/42-phrases-a-lexophile-would-love/
let messages = ['I wondered why the baseball was getting bigger. Then it hit me.','Police were called to a day care, where a three-year-old was resisting a rest.','Did you hear about the guy whose whole left side was cut off? He’s all right now.','The roundest knight at King Arthur’s round table was Sir Cumference.','To write with a broken pencil is pointless.','When fish are in schools they sometimes take debate.','The short fortune teller who escaped from prison was a small medium at large.','A thief who stole a calendar… got twelve months.','A thief fell and broke his leg in wet cement. He became a hardened criminal.','Thieves who steal corn from a garden could be charged with stalking.','When the smog lifts in Los Angeles , U. C. L. A.','The math professor went crazy with the blackboard. He did a number on it.','The professor discovered that his theory of earthquakes was on shaky ground.','The dead batteries were given out free of charge.','If you take a laptop computer for a run you could jog your memory.','A dentist and a manicurist fought tooth and nail.','A bicycle can’t stand alone; it is two tired.','A will is a dead giveaway.','Time flies like an arrow; fruit flies like a banana.','A backward poet writes inverse.','In a democracy it’s your vote that counts; in feudalism, it’s your Count that votes.','A chicken crossing the road: poultry in motion.','If you don’t pay your exorcist you can get repossessed.','With her marriage she got a new name and a dress.','Show me a piano falling down a mine shaft and I’ll show you A-flat miner.','When a clock is hungry it goes back four seconds.','The guy who fell onto an upholstery machine was fully recovered.','A grenade fell onto a kitchen floor in France and resulted in Linoleum Blownapart.','You are stuck with your debt if you can’t budge it.','Local Area Network in Australia : The LAN down under.','He broke into song because he couldn’t find the key.','A calendar’s days are numbered.',
];function randomMessage() {return messages[(Math.random() * messages.length) | 0];
}function appendChild() {let msg = document.createElement('div');msg.className = 'message';msg.innerText = randomMessage();scroller.insertBefore(msg, anchor);}
setInterval(appendChild, 1000);// To kick off effect immediately, this plus CSS
// document.scrollingElement.scroll(0, 1);
</script>

这里有两个小警告......

  1. 请注意,锚必须有一定的大小。我们在height这里使用以确保它不是没有大小的折叠/空元素,这会阻止它工作。
  2. 为了使滚动锚定起作用,页面必须至少滚动一次才能开始。

第二个更难。一种选择是根本不处理它,您可以等待用户滚动到底部,效果从那里开始起作用。实际上这很好,因为如果他们从底部滚动,效果就会停止工作,这就是你想要的。在上面的 JavaScript 版本中,请注意即使您尝试向上滚动,它也会迫使您进入底部,这就是 Ryan 的意思,这并不是一件容易正确的事情。

如果您需要立即启动效果,诀窍是让滚动元素立即可滚动,例如:

body {height: 100.001vh;
}

然后立即触发一个非常轻微的滚动:

document.scrollingElement.scroll(0, 1);

这应该可以解决问题。这些行可在上面的演示中取消注释并尝试。

CSS: overflow-anchor 固定滚动到底部,随着页面内容增多滚动条自己滚动展示最新的内容相关推荐

  1. vue 实现数据滚动显示_vue实现动态添加数据滚动条自动滚动到底部的示例代码...

    在使用vue实现聊天页面的时候,聊天数据动态加到页面中,需要实现滚动条也自动滚动到底部.这时我找到网上有个插件 vue-chat-scroll 但是安装后发现是用不了的,报错信息如下: VM14383 ...

  2. css方法div固定在网页底部

    css .bottom{width:100%;height:40px;background:#ededed;float:left;margin-bottom:0px;position:fixed;bo ...

  3. 聊天窗口内容滚动到底部的方法scrollTop和scrollIntoView

    测试内容样式: <style type="text/css">#container{overflow-y:auto; overflow-x:hidden; height ...

  4. datagridview滚动条自动滚动_Win32编程基础之滚动条

    (图片来源:游戏<ATRI> 通过使用滚动条,窗口可以显示比它大的文档或图片,用户可以滚动用户区中的数据对象来看到对象超出窗口边界的部分. 如果窗口的用户区比窗口的边框要大,窗口应该使用滚 ...

  5. 【移动端聊天功能模板】Vue实现H5聊天系统,实现上下固定中间滚动布局,微信授权功能,自动滚动到底部【详细注释,一看就会】

    前言 最近刚好在做这方面的功能,就网上看了下,发现很多种写法,但是有些写的很乱, 我也看的很麻烦,干脆就自己写一个简单的静态版本放在这, 以后需要用到的时候可以直接拿着改改就能用. 后面我还会继续更新 ...

  6. android html footer 固定,HTML5+CSS把footer固定在底部

    在刚开始给网页写footer的时候,我们会碰到一个让人烦躁的问题:当页面内容太少时,footer显示在了页面中间,这是我们不希望出现的,我们希望它能够永远呆在底部,不管网页的内容是多还是少.下面的代码 ...

  7. css 将标签固定在底部

    1.打开一个编辑软件设置一下css与div区域,使其固定在页面的底部 其主要属性:position:fixed; 绝对定位生成绝对定位的元素,相对于浏览器窗口进行定位. 2.网页中实现效果如下: 扩展 ...

  8. vue实现上下滑动翻页_vue 实现滚动到底部翻页效果(pc端)

    pc端vue 滚动到底部翻页 效果,具体内容如下所示: html: [{{item.code||item.name}}] {{item.name}} js: 先写滚动事件 handleScroll() ...

  9. [转]如何让DIV固定在页面的某个位置而不随着滚动条随意滚动

    首先,我们将目光投向了CSS规范,我想很多人和我一样很快就想到了position属性,说到定位,我们很容易想到这个属性.这个属性一共有四个 选项:static.relative.absolute.fi ...

最新文章

  1. 安装envi出现cannot find lincese_Ubuntu 16.04 安装 CUDA10.1 (解决循环登陆的问题)
  2. 线程池方式调用spring mvc的业务类的简单实例
  3. JVM:类加载机制之类加载器
  4. 系统学Android从零开始,搞懂这些直接来阿里入职
  5. 关于学力、同等学力与学历、同等学历的区别
  6. python调试神器_Python里三个最高逼格的调试神器
  7. Facebook斥资5亿美元 建设全风电数据中心
  8. win10如何安装系统得日语输入法(亲测)
  9. kvaser怎么用?Kvaser 汽车CAN通讯协议总线分析仪新手入门常见问题解决方案教程
  10. 【CSS 用户界面属性 (Basic user interface)】
  11. 不同vlan间通讯单臂路由和三层交换机
  12. git push failed to push some refs to xxxx 失败与解决方法
  13. 用户画像系列——推荐相关核心标签(偏好类)
  14. expdp报错ORA-39002: invalid operation,ORA-39070: Unable to open the log file
  15. android充电指示灯颜色修改
  16. 王者荣耀4.4日服务器维护,王者荣耀服务器正在维护中 4月4日王者荣耀维护到几点?...
  17. Java之每日经典一题:(1)珠穆朗玛峰
  18. STM32开发日记001:ARM和单片机之间的关系
  19. Android 开发艺术探索 源码地址
  20. 微信小程序预览word,doc,excel文件

热门文章

  1. 用python输入三个整数判断能否构成三角形_输入3个整数,判断是否能构成三角形,c语言编程...
  2. ArcMAP使用技巧小结
  3. Uncaught TypeError: xxx.push is not a function
  4. 扫地机器人粘住老鼠板怎么办_扫地机器人常见故障及维修方法
  5. 那些前端的特效(装哈哈神器)
  6. 微信小程序基础篇-模板与配置
  7. Python图片自动缩放到指定大小(不拉伸不改变精度)
  8. 产品项目分析之竞品分析
  9. 场效应管(FET)分类、符号、特性曲线
  10. 虚拟机RedHatEenterpriseLinux5安装及Oracle10.2.0安装手记收藏