Skip to content

Instantly share code, notes, and snippets.

@tammyhart
Created August 28, 2024 01:43
Show Gist options
  • Save tammyhart/08575ef2d4dc7b2b840b59d6ee9df15b to your computer and use it in GitHub Desktop.
Save tammyhart/08575ef2d4dc7b2b840b59d6ee9df15b to your computer and use it in GitHub Desktop.
A non-SVG solution to drawing a responsive line from top right to bottom left with circular markers on each end + calculate a gradient to fade from point a to b
import styled from "styled-components"
import { media, size } from "./utils"
enum Z {
Separator,
FauxLine,
FauxLineBlocker,
Marker,
}
const Markers = styled.div`
--border-width: ${size(0.75)};
--offset: ${size(10)};
position: relative;
z-index: ${Z.Separator};
overflow: clip;
height: var(--offset);
&::before,
&::after {
content: "";
position: absolute;
z-index: ${Z.Marker};
display: block;
width: 0;
height: 0;
border-radius: 50%;
border-style: solid;
border-width: var(--border-width);
}
&::before {
border-color: var(--color-accent);
left: var(--offset);
bottom: 0;
transform: translate(-50%, 50%);
}
&::after {
border-color: var(--color-background);
right: var(--offset);
top: 0;
transform: translate(50%, -50%);
}
${media.lap`
--offset: ${size(15)};
`}
${media.desk`
--border-width: ${size(1)};
--offset: ${size(20)};
`}
`
const Line = styled.div`
--line-weight: ${size(0.25)};
--line-weight-half: calc(var(--line-weight) / 2);
--border-radius: ${size(1.5)};
--border-radius-outside: calc(var(--border-radius) + var(--line-weight));
--color-start: var(--color-background);
--color-end: var(--color-accent);
--color-between: color-mix(in srgb, var(--color-start), var(--color-end));
position: absolute;
z-index: ${Z.FauxLine};
width: calc(50% - var(--offset) + var(--line-weight-half));
height: calc(50% + var(--line-weight-half));
&:nth-child(1) {
bottom: 0;
left: calc(var(--offset) - var(--line-weight-half));
border-top-left-radius: var(--border-radius-outside);
background: linear-gradient(
to bottom left,
var(--color-between) 0%,
var(--color-end) 100%
);
}
&:nth-child(2) {
top: 0;
right: calc(var(--offset) - var(--line-weight-half));
border-bottom-right-radius: var(--border-radius-outside);
background: linear-gradient(
to bottom left,
var(--color-start) 0%,
var(--color-between) 100%
);
}
&::before {
content: "";
display: block;
position: absolute;
inset: 0;
z-index: ${Z.FauxLineBlocker};
background: var(--color-base);
}
&:nth-child(1)::before {
margin-top: var(--line-weight);
margin-left: var(--line-weight);
border-top-left-radius: var(--border-radius);
}
&:nth-child(2)::before {
margin-right: var(--line-weight);
margin-bottom: var(--line-weight);
border-bottom-right-radius: var(--border-radius);
}
${media.desk`
--line-weight: ${size(0.5)};
`}
`
const Separator = () => (
<Markers>
<Line />
<Line />
</Markers>
)
export default Separator
export type Size = 0.25 | 0.5 | 0.75 | 1 | 1.5 | 10 | 15 | 20 | 100 | 150
import { css } from "styled-components"
import type { Size } from "./styles"
export const size = (_size: Size) => _size * 8 + "px"
const LAP = "lap"
const DESK = "desk"
const deviceSizes = [LAP, DESK] as const
type DeviceSizes = (typeof deviceSizes)[number]
const device = {
[LAP]: size(100),
[DESK]: size(150),
}
const mediaStyles =
(deviceSize: DeviceSizes) =>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(literals: TemplateStringsArray, ...rest: any[]) =>
css`
@media (min-width: ${device[deviceSize]}) {
${css(literals, ...rest)};
}
`
export const media = {
[LAP]: mediaStyles(LAP),
[DESK]: mediaStyles(DESK),
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment