I would use a combination of overflow, overflow-wrap and white-space to make the text break correctly.
Then I would use a pseudo element to render the item count after the container.
By putting it absolute, we can align ther element relative to the container, no matter how many extra nodes we add to the container.
Since we use a pseudo-element, we can easily use the content
css rule to bind the data-items attribute of the HTML container as the content of our little counter.
The big advantage is that by positioning the counter absolutely, we can keep using relative units to position everything else and we can put the counter anywhere we want, including putting overflow back on hidden and have the counter overlap the border.
const cities = [
"amsterdam",
"belize",
"calcutta",
"dortmund",
"egmond aan zee",
"frankfurt",
"gotenburg"
];
const render_list = list => content => {
const items = content.map( text => `<li>${ text }</li>` ).join( '' );
list.innerHTML = items;
return list;
};
const add_city = list => event => {
const item = event.target;
if ( event.target.nodeName === 'LI' ) {
list.appendChild( item.cloneNode(true));
list.setAttribute( 'data-items', list.childElementCount );
}
};
const options = document.querySelector( '#options' );
const selections = document.querySelector( '#selections' );
options.addEventListener( 'click', add_city( selections ));
render_list( options )( cities );
#selections {
background-color: steelblue;
border: 1px solid grey;
list-style: none;
margin: 4px;
max-width: 50%;
min-height: 1.1em;
overflow-wrap: break-word;
position: relative;
width: 50%;
}
#selections:after {
background-color: white;
border: 1px solid grey;
content: '+' attr(data-items);
position: absolute;
left: 100%;
top: -1px;
}
#selections > li {
display: inline;
margin-left: 2px;
}
#options {
border: 1px solid grey;
margin-top: 20px;
}
<ul data-items="0" id="selections"></ul>
<ul id="options"></ul>