Как ограничить ширину span по фактически занимаемому буквами пространству?
В span есть стрелочка сортировки, она позиционируется абсолютно относительно span. Но когда происходит перенос строки, то образуется промежуток между тестом span и стрелочкой. Мне нужно, чтобы span занимал ширину по факту, сколько занимается ширины тест (чтобы не было промежутка). Есть ли такая возможность?
const CriteriaSelector: React.FC<ICriteriaSelectorProps> = ({
label,
sortCriteria,
sortHook,
className,
}) => {
return (
<div
className={classNames(styles.criteriaSelector, className)}
onClick={() => sortHook.recountSort(sortCriteria)}
>
<span
className={classNames(
styles.label,
sortCriteria === sortHook.sortCriteria && styles.active
)}
>
{label}
{sortHook.sortMode != ESortMode.noSort &&
sortCriteria === sortHook.sortCriteria && (
<svg
className={classNames(
styles.arrow,
sortHook.sortMode === ESortMode.ascendingOrder &&
styles.arrow_reverse
)}
viewBox="0 0 8 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 6L0.535898 6.52533e-07L7.4641 4.68497e-08L4 6Z"
fill="#606773"
/>
</svg>
)}
</span>
</div>
);
};
.criteriaSelector {
position: relative;
cursor: pointer;
user-select: none;
max-width: 200px;
.label {
position: relative;
display: inline-block;
.arrow {
position: absolute;
aspect-ratio: 1.333 / 1;
width: 8px;
left: calc(100% + 8px);
top: 50%;
transform: translateY(-50%);
transition: transform 150ms ease;
@include breakpoint(sm) {
left: calc(100% + 2px);
width: 7px;
}
&_reverse {
transform: translateY(-50%) scale(1, -1);
}
}
}
Ответы (1 шт):
Я ровным счетом ничего с Вашим кодом не делал, кроме преобразования его под ванильные HTML и CSS таким образом видно, что в Firefox не воспроизводит проблему.
.criteriaSelector {
position: relative;
cursor: pointer;
user-select: none;
max-width: 200px;
}
.criteriaSelector .label {
position: relative;
display: inline-block;
}
.criteriaSelector .arrow {
position: absolute;
aspect-ratio: 1.333;
width: 8px;
left: calc(100% + 8px);
top: 50%;
transform: translateY(-50%);
transition: transform 150ms ease;
}
.criteriaSelector .arrow_reverse {
transform: translateY(-50%) scale(1, -1);
}
<div class="criteriaSelector">
<span class="label active">
<a href="#">Транспорт, дата и время возврата в г.Новосибирск</a>
<svg
class="arrow arrow_reverse"
viewBox="0 0 8 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 6L0.535898 6.52533e-07L7.4641 4.68497e-08L4 6Z"
fill="#606773"
/>
</svg>
</span>
</div>
<br>
<div class="criteriaSelector">
<span class="label active">
Транспорт, дата и время возврата в г.Новосибирск
<svg
class="arrow"
viewBox="0 0 8 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 6L0.535898 6.52533e-07L7.4641 4.68497e-08L4 6Z"
fill="#606773"
/>
</svg>
</span>
</div>
Решение для Chrome пока предварительное с добавлением свойства width cо значением min-content:
.criteriaSelector {
position: relative;
cursor: pointer;
user-select: none;
max-width: 200px;
}
.criteriaSelector .label {
position: relative;
display: inline-block;
width: min-content;
}
.criteriaSelector .arrow {
position: absolute;
aspect-ratio: 1.333;
width: 8px;
left: calc(100% + 8px);
top: 50%;
transform: translateY(-50%);
transition: transform 150ms ease;
}
.criteriaSelector .arrow_reverse {
transform: translateY(-50%) scale(1, -1);
}
<div class="criteriaSelector">
<span class="label active">
<a href="#">Транспорт, дата и время возврата в г.Новосибирск</a>
<svg
class="arrow arrow_reverse"
viewBox="0 0 8 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 6L0.535898 6.52533e-07L7.4641 4.68497e-08L4 6Z"
fill="#606773"
/>
</svg>
</span>
</div>
<br>
<div class="criteriaSelector">
<span class="label active">
Транспорт, дата и время возврата в г.Новосибирск
<svg
class="arrow"
viewBox="0 0 8 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 6L0.535898 6.52533e-07L7.4641 4.68497e-08L4 6Z"
fill="#606773"
/>
</svg>
</span>
</div>
Если задать еще и min-width например со значением 175px можно добиться желаемого результата, но этот вариант не всегда гарантирует такое поведение (с другим текстом может быть иначе)
В качестве дополнительного варианта решения этой задачи можно воспользоваться функцией вставки неразрывных пробелов
В Вашем конкретном случае использование будет таким:
{textUpdate(label)}
function textUpdate(text){
const symb = String.fromCharCode(160) //  
const widthLine = 35 // ширина надписи в символах
const indexes = Array.from(text.matchAll(/ /g))
.map(e => e.index).filter(e => e < widthLine)
return = text.slice(0, indexes.slice(-1))
.replace(/ /g, symb) + text.slice(indexes.slice(-1))
}
let el = document.querySelector('.label.active a')
el.textContent = textUpdate(el.textContent)
.criteriaSelector {
position: relative;
cursor: pointer;
user-select: none;
max-width: 200px;
}
.criteriaSelector .label {
position: relative;
display: inline-block;
}
.criteriaSelector .arrow {
position: absolute;
aspect-ratio: 1.333;
width: 8px;
left: calc(100% + 8px);
top: 50%;
transform: translateY(-50%);
transition: transform 150ms ease;
}
.criteriaSelector .arrow_reverse {
transform: translateY(-50%) scale(1, -1);
}
<div class="criteriaSelector">
<span class="label active">
<a href="#">Транспорт, дата и время возврата в г.Новосибирск</a>
<svg
class="arrow arrow_reverse"
viewBox="0 0 8 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 6L0.535898 6.52533e-07L7.4641 4.68497e-08L4 6Z"
fill="#606773"
/>
</svg>
</span>
</div>



