I have an icon that shows only when I hover over a container. It’s currently position relative because I need it to stay within the container. With it being relative though it pushes down the rest of the items within the container; however, I want them to stay vertically centered. I know I could use negative margin to force them back up, but that is typically seen as bad practice so I’m trying to figure out another way to handle this.
^^ What the front end looks like with the position relative, the icon stays within the white container.
^^ What the front end looks like with the position absolute, no matter where I position the icon its gonna be on the same spot on the screen regardless of which container I hover over.
This is the react code for the scrolling list of containers
return (
<div className="container mx-auto p-4">
<h1 className="text-4xl font-bold text-center mb-6 text-amber-100">Task List</h1>
<div className="overflow-x-auto scrollbar-custom">
<ul className="flex space-x-4 mb-10 blue" style={{ listStyleType: 'none', padding: 0 }}>
{ tasks.map((task) =>
(
<li key={task.id}
className="TaskBox bg-white shadow-lg shadow-amber-200/60 rounded-lg p-8 shadow-sm min-w-[300px] max-w-[300px] flex-shrink-0">
<div className="deleteTask">
<DeleteTask task={task}/>
</div>
<div className="TaskInfo">
<h4 className="text-2xl font-semibold text-gray-800 mb-2">{task.title}</h4>
<p className="text-sm text-gray-500 mb-2"
>Created on: {new Date(task.createdAt).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})}</p>
<p className="text-gray-600 mb-4">{task.description}</p>
<p className={`text-sm ${task.isCompleted ? 'text-green-500' : 'text-red-500'}`}>Completed: {task.isCompleted ? 'Yes' : 'No'}</p>
</div>
</li>
))}
</ul>
</div>
</div>
);
CSS for the code
.trashIcon
{
width: 1.75em;
height: 1.95em;
color: indianred;
transition: transform 0.15s ease;
}
.deleteTask:hover .trashIcon
{
transform: scale(1.1);
color: firebrick;
}
.deleteTask
{
position: absolute !important;
left: 50%;
bottom: 12%;
padding: 6px 6px;
background-color: lightslategray;
border-radius: 12px;
transition: transform 0.15s ease;
visibility: hidden;
}
.deleteTask:hover
{
background-color: dimgrey;
}
.TaskBox:hover .deleteTask
{
display: inline-block;
transform: scale(1.1);
visibility: visible;
}
.TaskInfo
{
display: flex-column;
justify-content: center;
align-items: center;
}
.newTaskForm
{
width: 50%;
}
I tried switching to position absolute as it doesn’t effect other DOM elements, I was expecting it to stay within the white container though, but it only stays within the container like shown in the first picture with position relative.
>Solution :
You need to add "relative" as a className to your card, so the absolute className has something to refer to for its placement.
This should work:
return (
<div className="container mx-auto p-4">
<h1 className="text-4xl font-bold text-center mb-6 text-amber-100">Task List</h1>
<div className="overflow-x-auto scrollbar-custom">
<ul className="flex space-x-4 mb-10 blue" style={{ listStyleType: 'none', padding: 0 }}>
{ tasks.map((task) =>
(
<li key={task.id}
className="relative TaskBox bg-white shadow-lg shadow-amber-200/60 rounded-lg p-8 shadow-sm min-w-[300px] max-w-[300px] flex-shrink-0">
<div className="deleteTask">
<DeleteTask task={task}/>
</div>
<div className="TaskInfo">
<h4 className="text-2xl font-semibold text-gray-800 mb-2">{task.title}</h4>
<p className="text-sm text-gray-500 mb-2"
>Created on: {new Date(task.createdAt).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})}</p>
<p className="text-gray-600 mb-4">{task.description}</p>
<p className={`text-sm ${task.isCompleted ? 'text-green-500' : 'text-red-500'}`}>Completed: {task.isCompleted ? 'Yes' : 'No'}</p>
</div>
</li>
))}
</ul>
</div>
</div>
);

