JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.10.0/Sortable.min.js"></script>
<div id="mylist" class="sortable-list-wrapper"></div>
<button type="button" id="addNewListItem">Add list item</button>
SCSS
body {
font-family: sans-serif;
padding: 5em;
}
.sortable-list-wrapper {
min-height: 5em;
border: 2px dashed #ccc;
margin: 0 0 1em;
padding: 1em;
div {
position: relative;
display: block;
border: 2px solid #ccc;
padding: 0.6em;
+ div {
margin-top: 0.3em;
}
&:hover span {
z-index: 2;
}
}
span {
display: block;
position: absolute;
top: 0.6em;
right: 0.6em;
margin-left: 0.3rem;
color: #f00;
&:after {
content: attr(data-explain);
position: absolute;
top: 100%;
left: 50%;
transform: translate(-50%, 0.5em);
background: rgba(#333, 0.8);
color: #fff;
white-space: nowrap;
padding: 0.5em;
display: none;
animation: showTooltip 0.3s ease-out;
}
&:hover:after {
display: block;
}
}
}
@keyframes showTooltip {
from: {
opacity: 0;
transform: translate(-50%, -0.5em);
}
}
JavaScript
let list = document.getElementById('mylist');
let button = document.getElementById('addNewListItem');
// ID (for testing only)
let id = 1;
// Create new list item
function ListItem() {
this.wrapper = document.createElement('div');
this.wrapper.textContent = 'List item ' + id;
this.tooltip = document.createElement('span');
this.tooltip.textContent = '[?]';
this.tooltip.dataset.explain = 'I am a tooltip';
this.wrapper.appendChild(this.tooltip);
id++;
return this.wrapper;
}
// Create 'sortable'
new Sortable(list, {
group: 'random-group'
});
// Make list addable
button.addEventListener('click', () => {
list.appendChild(new ListItem());
});