<div class="profile">
<div class="profile__header" data-art data-start-color="#41cbd3" data-end-color="#48e2df">
<div class="profile__avatar">
<img class="profile__avatar-image" src="https://images.unsplash.com/photo-1641579281152-e5d633aa3775?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=maxim-berg-6-NP_CdNqtU-unsplash.jpg&w=640" alt="" />
</div>
</div>
<div class="profile__body">
<p class="profile__name">John Doe</p>
</div>
</div>
body {
min-height: 100vh;
margin: 0;
padding: 32px;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
font: 18px 'Segoe UI', Arial, Helvetica, sans-serif;
background: linear-gradient(60deg, #b2d8e5, #cabfea);
}
.profile {
--avatar-radius: 120px;
--avatar-gap: 12px;
min-width: 400px;
border-radius: 24px;
display: flex;
flex-direction: column;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.15),
0 4px 4px rgba(0, 0, 0, 0.1),
0 8px 8px rgba(0, 0, 0, 0.05);
overflow: hidden;
&__header {
position: relative;
height: 192px;
border-radius: 24px 24px 0 0;
background-color: #41cbd3;
&::after,
&::before {
position: absolute;
content: '';
z-index: 0;
}
&::before {
top: 0;
right: -16px;
bottom: 0;
left: -16px;
box-shadow: inset 0 -2px 2px rgba(0, 0, 0, 0.1),
inset 0 -4px 4px rgba(0, 0, 0, 0.05);
}
&::after {
top: 100%;
left: 50%;
width: calc(var(--avatar-radius) + var(--avatar-gap) * 2);
height: calc(var(--avatar-radius) + var(--avatar-gap) * 2);
border-radius: 50%;
box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.1),
0 0 4px 4px rgba(0, 0, 0, 0.05);
transform: translate(-50%, -50%);
}
}
&__avatar {
position: absolute;
top: 100%;
left: 50%;
width: var(--avatar-radius);
height: var(--avatar-radius);
padding: var(--avatar-gap);
border-radius: 50%;
background-color: #ffffff;
transform: translate(-50%, -50%);
z-index: 2;
&-image {
width: 100%;
height: 100%;
border-radius: 50%;
object-fit: cover;
display: block;
}
}
&__body {
padding: 72px 16px 32px 16px;
border-radius: 0 0 24px 24px;
background-color: #ffffff;
z-index: 1;
}
&__name {
margin: 0;
text-align: center;
font-size: 2rem;
}
}
View Compiled
const pick = array => array[Math.floor(Math.random() * array.length)];
document.querySelectorAll('[data-art]').forEach(container => {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const rect = container.getBoundingClientRect();
[canvas.width, canvas.height] = [rect.width, rect.height];
const radius = 24;
const gap = 4;
const size = radius * 2 + gap;
const tau = Math.PI * 2;
const angles = [0, Math.PI / 2, Math. PI, Math.PI * 3 / 2];
const countX = Math.ceil(canvas.width / size) + 1;
const countY = Math.ceil(canvas.height / size) + 1;
const offsetX = ((countX % 2 === 0 ? countX : countX - 1) * size - canvas.width) / -2;
const offsetY = ((countY % 2 === 0 ? countY : countY - 1) * size - canvas.height) / -2;
const { startColor = 'transparent', endColor = 'transparent' } = container.dataset;
const circle = () => {
context.beginPath();
context.arc(0, 0, radius, 0, tau);
context.closePath();
context.fill();
};
for (let x = 0; x < countX; x++) {
for (let y = 0; y < countY; y++) {
const offset = y % 2 !== 0 ? size / 2 : 0;
const centerX = x * size + offset;
const centerY = y * size;
context.save();
context.translate(centerX + offsetX, centerY + offsetY);
const angle = pick(angles);
const rotationX = Math.cos(angle);
const rotationY = Math.sin(angle);
context.save();
context.shadowColor = endColor;
context.shadowBlur = 4;
context.shadowOffsetX = -rotationX;
context.shadowOffsetY = -rotationY;
context.fillStyle = startColor;
context.globalAlpha = 0.25;
circle();
context.restore();
const gradient = context.createLinearGradient(
rotationX * -radius, rotationY * -radius,
rotationX * radius, rotationY * radius
);
// const gradient = context.createRadialGradient(
// rotationX * radius * 3, rotationY * radius * 3, radius,
// rotationX * radius * 3, rotationY * radius * 3, radius * 4.5
// );
gradient.addColorStop(0.5, startColor);
gradient.addColorStop(1, endColor);
context.fillStyle = gradient;
circle();
context.restore();
}
}
container.prepend(canvas);
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.