关于浮动元素,你还在自己计算位置吗?来看看 Floating UI 吧
什么是浮动元素?就是在页面布局之外浮动,而不会破坏页面布局的元素。浮动元素在实际项目中有广泛的使用。比如工具提示、弹出框、下拉菜单等。拿掘金举例。比如这样:
优势
跨平台兼容
浮动元素不只是 HTML 独有的需求,在移动端、Canvas、WebGL 等其他通过 JavaScript 编写的环境中,都有这个需求。所以 Floating UI 可以在原生 JS、React、React Native 等环境中使用。
体积
Floating UI 的体积仅有 600 b,而且它支持摇树。相比之下 Popper 3kb 的体积,并且不可摇树,显得非常臃肿了。
快速入门
安装
Floating UI 有好几个包,分别对应不同的平台。下面是 Web 平台的包。
npm i @floating-ui/dom
如果想省事,还可以使用 ESM 格式通过 CDN 来加载 Floating UI。
<script type="module"> import * as FloatingUIDOM from 'https://cdn.skypack.dev/@floating-ui/dom'; </script>
computePosition
computePosition 是 Floating UI 的核心 API,它可以通过计算浮动元素的坐标将其定位在参考元素旁边。我们利用这个 API 制作一个工具提示来尝试一下。这是 html 部分。
<button id="button" aria-describedby="tooltip">我是一个按钮</button>
<div id="tooltip" role="tooltip">我是一个悬浮的工具提示</div>
包含了一个按钮一个 div,我们想让 div 浮动到按钮的正下方。再来添加一些样式。
#tooltip {color: #fff;background: #363636;font-size: 1.2rem;padding: 10px 15px;border-radius: 8px;position: absolute;box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1), 0 3px 3px rgba(0, 0, 0, 0.05);
}button {border-radius: 8px;border: none;outline: none;font-size: 1.2rem;cursor: pointer;padding: 10px 15px;color: #fff;background: rgb(48, 19, 129);
}
最后实现我们的功能。
import { computePosition } from "https://cdn.skypack.dev/@floating-ui/dom";const button = document.querySelector("#button");
const tooltip = document.querySelector("#tooltip");computePosition(button, tooltip).then(({ x, y }) => {Object.assign(tooltip.style, {left: `${x}px`,top: `${y}px`,});
});
我们首先获取到两个元素,button 是参考元素,tooltip 是浮动元素。然后通过异步计算,得到 x 和 y 的坐标,设置到浮动元素上,完成定位。我们还可以设置元素不同的位置,这通过 computePosition 的第三个参数来完成。
computePosition(button, tooltip , { placement: 'top-start' })
placement 可以指定浮动元素应该靠近参考元素的哪一侧。
- left-start
- left
- left-end
- top-start
- top
- top-end
- right-start
- right
- right-end
- bottom-start
- bottom
- bottom-end
默认值是 bottom。
中间件
Floating UI 还提供了中间件的概念,就是在调用 computePosition 之后,then 之前运行的一段代码,可以改变浮动元素的定位和行为。中间件是实现除了基本定位功能之外的其他功能统一的方式。Floating UI 提供了下面几个中间件:
- offset:修改参考元素和浮动元素之间的间距
- shift:移动浮动元素,让它保持始终可见。它还会处理元素溢出到窗口之外的情况。
- flip:帮我们修改坐标,如果我们设置浮动元素在顶部,但是距离顶部太近,会放置到底部。
- size:调整浮动元素的大小。
- autoPlacement:通过选择可用空间最多的位置来自动确定浮动元素的位置。
- inline:改进跨多行的内联元素的定位,比如 a 标签。
使用中间件:
computePosition(button, tooltip, {placement: "top",middleware: [offset(4), flip(), shift({padding: 5})],
}).then(({ x, y }) => {// ...
});
中间件的使用也是有顺序的,比如 offset 应该始终处于数组的第一个位置。
交互
到现在为止,我们也只是解决了定位的问题。交互的问题还没有处理。现在工具提示是一直显示的,通常情况下,它应该默认是隐藏状态,当我们通过某种交互事件后,它才会显示。比如点击、鼠标悬停等。为了实现交互功能,我们需要封装代码。
function setUpTooltip() {computePosition(button, tooltip, {placement: "top",middleware: [offset(4), flip(), shift({ padding: 5 })],}).then(({ x, y }) => {Object.assign(tooltip.style, {left: `${x}px`,top: `${y}px`,});});
}function showTooltip() {tooltip.style.display = "block";setUpTooltip();
}function hideTooltip() {tooltip.style.display = "none";
}
现在只需要调用 showTooltip 就可以控制元素显示,调用 hideTooltip 就可以控制元素隐藏。我们把这两个函数绑定到元素的鼠标移入移出事件上。
[["mouseenter", showTooltip],["mouseleave", hideTooltip],
].forEach(([event, listener]) => {button.addEventListener(event, listener);
});
现在功能就全部完成了。
在 React 中使用 Floating UI
在 React 中使用 Floating UI 非常友好,它提供了对应的包,我们只需要换成这个包就可以了。
npm install @floating-ui/react-dom
要实现上面演示的原生案例,对应的 React 代码如下:
import { useFloating, shift, offset, flip, useInteractions, useHover } from "@floating-ui/react-dom";export default function App() {const [open, setOpen] = useState(true);const { x, y, reference, floating, strategy, context } = useFloating({placement: "right",middleware: [offset(4), flip(), shift({ padding: 5 })],open,onOpenChange: setOpen,});const { getReferenceProps, getFloatingProps } = useInteractions([useHover(context),]);return (<><button ref={reference} {...getReferenceProps()}>Button</button>{ open && <divid="tooltip"ref={floating}style={{ top: y, left: x }}{...getFloatingProps()}>Tooltip</div>}</>);
}
可以看到,Floating UI 在 React 中具有了更多的功能,比如提供了 useInteractions Hook 帮助我们处理交互的问题。
总结
通过在几个项目中使用 Floating UI,我总结出的优点有以下几个:
- API 友好,几乎不需要多做其他事情。
- 文档和示例完善,可以去官网上复制代码。
- 体积小,支持摇树,性能更好。
- 跨环境,有 JavaScript 的地方就可以使用。
- 跨框架,原生、React、Vue 等都可以使用。
总结
通过在几个项目中使用 Floating UI,我总结出的优点有以下几个:
- API 友好,几乎不需要多做其他事情。
- 文档和示例完善,可以去官网上复制代码。
- 体积小,支持摇树,性能更好。
- 跨环境,有 JavaScript 的地方就可以使用。
- 跨框架,原生、React、Vue 等都可以使用。
关于 Floating UI 的介绍就到这里,快去试试吧。
关于浮动元素,你还在自己计算位置吗?来看看 Floating UI 吧相关推荐
- CSS - 浮动元素的margin-left和margin-right
marigin-left和margin-right理解 margin-left:"盒子"元素的左外边距,当属性值增大,元素表现为向右移动,该属性值减少,元素表现为向左移动. mar ...
- 定义了浮动元素后margin-bottom失效的解决办法
2019独角兽企业重金招聘Python工程师标准>>> 虽然IE6慢慢的退出市场了,但是还是有必要了解一些兼容问题,让自己的知识有一个更好的沉淀.margin-bottom的bug是 ...
- 修复IE的浮动元素双倍边距Bug
CSS开发人员可能经常会碰到的一个现象是,一个页面在IE(特别是老版本的IE)中显示正常,而在现代浏览器中却完全变形了,或者情况完全相反. 常常能听到有人抱怨:"在IE上开发时间中,超过 6 ...
- 关于浮动元素float使其父元素高度塌陷的原因及解决方法
浮动元素使其父级元素高度塌陷 在没有设置浮动前(父级元素背景色为黑色) 给两个子元素设置左浮动后,在示例中仿佛父元素消失了,其实父元素并没有消失,只是高度被计算为0.这就要回到浮动元素的特性来说明此问 ...
- 浮动元素会引起的问题和你的解决办法
问题: (1)父元素的高度无法被撑开,影响与父元素同级的元素 (2)与浮动元素同级的非浮动元素会跟随其后 (3)若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构 解决方法: ...
- CSS浮动元素特点有什么
什么是浮动? 元素的浮动是指设置了浮动属性(flot)的元素. CSS浮动有什么作用? 1.让多个盒子水平排列成一行,浮动成为布局的重要手段; 2.可以实现盒子的左右对齐等等; 3.浮动最早是用来控制 ...
- 已知/未知宽高的浮动元素水平居中对齐 和 图片水平垂直居中对齐
一.已知宽高的浮动元素水平垂直居中对齐 效果: 样式CSS: 1 <style> 2 .parent{ 3 position:relative; 4 border:2px solid #0 ...
- 一句white-space:nowrap解决IE6,IE7下浮动元素不自动换行
一句white-space:nowrap解决IE6,IE7下浮动元素不自动换行 转载于:https://www.cnblogs.com/mabelstyle/p/3844739.html
- CSS学习笔记--浮动元素由于浏览器页面缩小而被挤到下面的解决方法
CSS学习笔记--浮动元素由于浏览器页面缩小而被挤到下面的解决方法 参考文章: (1)CSS学习笔记--浮动元素由于浏览器页面缩小而被挤到下面的解决方法 (2)https://www.cnblogs. ...
- 浮动元素的display属性
在页面布局的时候,我们经常会将元素设置成浮动效果来解决一些实际问题,无论当前元素是块级元素还是行内元素, 似乎都有需要设置成浮动的时候,但与此同时,我们有没有想过,在元素被设置成浮动之后,他们的blo ...
最新文章
- 带你遍历用户生命价值与流失挽救(上) : 流量下的价值套路
- mysql 插入加锁_MySQL 是怎么死锁的?
- PHP中怎样实现正负数的相加,PHP 求任意n个正负整数里面最大的连续和
- bootstrap 点击按钮刷新_Spring Cloud 中的 Bootstrap 上下文
- python sorted下标_Python学习教程(Python学习路线):第七天-字符串和常用数据结构
- 获2017中国最佳创业投资机构百强,西高投二次创业实现超越
- 你有哪些“相见恨晚”的 UE4 学习资料?
- simnow账户无法使用,simnow账户修改密码
- 基于R语言对哺乳动物睡眠时间sleep数据集的分析
- 在拼多多上抢了点茅台
- 腾讯全民wifi如何?
- EasyExcel学习笔记
- php异步执行shell脚本
- 有哪些能给视频加特效字幕的软件?试试这几种简单方法
- 理解elasticsearch
- 【TCP wrappers】关于/etc/hosts.allow /etc/hosts.deny
- [Unity]实现按住WASD角色移动
- Python基础课程-面向对象编程
- 关于相机飞拍和IO板卡触发拍照
- 苹果手机以旧换新活动_苹果中国宣布以旧换新活动延期至3月25日