这几天老板丢出一个想要的效果来:
于是UI领略了老板的意图, 做出这样的样式
呵, 仰天大笑出门去, 我辈岂是蓬蒿人。该功能使用 react + styled-components 完成
相对于浏览器的 tab 页, 这个更难点:
浏览器tab的难点:外圆角的实现
我们tab实现的难点在于:
- 每一个 tab 的颜色不同, 且偶数会压着基数《不是单纯的颜色区分》, 但是基数会填充偶数tab背景
- 我们的 tab 有一个边框线隔离
分析
- 先实现外圆角《radial-gradient《镜像渐变实现外圆》, 伪元素(::after, ::before), 三部分进行拼接》
- 画出外圆角 border《长方形上圆角弧度 + 圆形剪切, 三部分拼接实现border》
- 并排《存有空隙》
- 找出规律, 使用定位完成《利用 z-index , width, left 实现》
实现
// 这是一个获取随机颜色的算法
const getTeamColor:() => string = () => '#f00'
<WorkFolderHeader>
{ getTeamSort().map((team, index) => (
<OutborderBox index={index} color={getTeamColor()}>
<div className="left"></div>
<div className="team-name">{team.name}</div>
<div className="right"></div>
</OutborderBox>
))}
</WorkFolderHeader>
export const WIDTH = 314;
export const WorkFolderHeader = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 45px;
border-bottom: 1px solid #f0f0f0;
position: relative;
`;
export const OutborderBox = styled.div<{ index: number; color?: string }>`
position: absolute;
top: 0;
height: 100%;
line-height: 45px;
background-color: ${({ color }) => color};
box-sizing: border-box;
:nth-child(2n + 1) {
left: ${({ index }) => index * WIDTH - 10}px;
min-width: ${WIDTH + 20}px;
max-width: ${WIDTH + 20}px;
z-index: 0;
border-radius: 0;
> .team-name {
padding: 0 20px;
}
}
:nth-child(2n) {
left: ${({ index }) => index * WIDTH}px;
min-width: ${WIDTH}px;
max-width: ${WIDTH}px;
z-index: 1;
border-radius: 10px 10px 0 0;
> .team-name {
padding: 0 10px;
}
}
> .team-name {
width: 100%;
word-break: keep-all;
overflow: hidden;
text-overflow: ellipsis;
::before {
content: '';
position: absolute;
left: -10px;
bottom: 0;
width: 10px;
height: 10px;
background: ${({ color }) =>
'radial-gradient(circle at 0% 0%, transparent 10px, ' + color + ' 0)'};
}
::after {
content: '';
position: absolute;
right: -10px;
bottom: 0;
width: 10px;
height: 10px;
background: ${({ color }) =>
'radial-gradient(circle at 100% 0%, transparent 10px, ' + color + ' 0)'};
}
}
> .left,
> .right {
position: absolute;
bottom: 0px;
border-radius: 50%;
width: 20px;
height: 20px;
border: 1px solid #f0f0f0;
z-index: 3;
}
> .left {
left: -20px;
clip-path: circle(50% at 100% 100%);
}
> .right {
right: -20px;
clip-path: circle(50% at 0% 100%);
}
:not(:first-child) {
border-left: 1px solid #f0f0f0;
border-right: 1px solid #f0f0f0;
}
:last-child {
min-width: ${WIDTH + 10}px;
max-width: ${WIDTH + 10}px;
overflow: hidden;
}
`;