Комментарии 16
Не самый удачный подход, пусть и имеет право на жизнь
Во первых, в 90% случаев стоит прежде чем рассказывать за кастомные тултипы, рассказать что почти наверняка достаточно использовать пакет/библиотеку с ними
Во вторых, для отображения/не отображения блока по ховеру хватит и такой конструкции (чуть упрощаю)
.parent{
& .tooltip{
display: none
}
&:hover .tooltip{
display: block
}
}
И как раз вот тут можно аккуратно навесить анимацию, не используя тяжеловесный СSSTransition
В третьих, кнопка у Вас просит на себя нажать, а ручка приделана к ховеру
Ну и наконец, на устройствах с сенсорным экраном нужно проверить, будет ли работать код выше - могу ошибиться, но вроде бы нет
display: none - всего лишь скрывает видимость блока, а по факту его React рендерит в dom.
Зачем в dom лишние элементы, которые может никогда может и не будут показаны в основной своей массе?
А если таких элементов много на странице?
Например - прокручиваемый список из элементов в каждом из котрых есть тултип скрытый display: none, предствьте как у вас dom раздует.
ИМХО: display: none - это совсем не в философии React
Если говорить про философию Реакта, то намного более разумно положить где-то поближе к корню ReactModalPortal и пробрасывать коллбек туда, например - используя контексты или MobX. Т.е. те самые порталы
И уже там отрисовывается через display
По поводу того, что Реакт рендерит блок при загрузке страницы - да, такое есть. Зато у вас при показе/сокрытии модалки компонент ремаунтится. Поэтому для тех случаев, в которых модалки применяются чаще всего - подходы как минимум сопоставимы в плане перфоманса. Да и условный рендеринг - не совсем бесплатная штука
А вот читаемость у решения в статье как минимум спорная, имхо
на сенсорном экране hover считается как клик и замирает в положении наведения.
Через display: none нельзя будет управлять состоянием показа до наведения.
Напрмер, показывать tooltip если валидация не прошла.
И касательно тяжеловесности CSSTransition. В сбилденном варианте его минимизированный JS файл = 3,63 kb, а минимизированный CSS файл = 2,28 kb. Вы считаете что 5,91 kb в бандле, это много для тех возможностей, что CSSTransition предоставляет для анимации в React приложении?
Что произойдет с подсказкой, если компонент к которому она показывается, будет внутри контейнера с overflow: hidden?
Лучше использовать порталы для решения этой проблемы, иначе можно столкнуться с "войной миров z (индексов)" и обрезанием тултипа родительским блоком. А еще лучше взять что-то типа https://floating-ui.com/ , чтобы учесть скролл, невлезание тултипа в нужном месте и тд
Я конечно не фронтендщик и не UI/UX дизайнер, но мне подобная подсказка появляющаяся в рандомном месте сайта очень не нравится. Я привык к подсказкам из под курсора - куда смотришь, там и читаешь. И на мой скромный вкус, лучше такого классического "из_под_курсорного" варианта нет. Поэтому за старание я конечно могу поставить автору + но вот за UX точно -.
Не очень понимаю, зачем вам столько кода ради одного тултипа, так можно быстро выгореть не доходя до релиза. Позвольте, предложу свой вариант, которым пользуюсь , правда я это называю hints
*[data-hint] {
position: relative;
}
*[data-hint]:hover:after {
visibility: visible;
transform: translate(-50%, -100%);
}
*[data-hint]:after {
visibility: hidden;
position: absolute;
transition: transform .2s ease;
top: -3px;
left: 50%;
z-index: 2;
transform: translate(-50%, 0%);
background-color: var(--color-blue-gray-700);
color: #fff;
content: attr(data-hint);
display: inline-block;
padding: 3px;
border-radius: 3px;
font-size: 0.8em;
line-height: 0.8em;
}
вот и все. пользоваться просто `<span data-hint="вот так могу">подсказка</span>` и сэкономленное время можно потратить на изучение более серьезных подходов в сайтостроении
Спасибо за комент.
Отличный подход через возможность абсолютного позиционирования псевдоэлемента :after для создания минималистичного тултипа.
Реализовал ваш подход в ветке OnlyCss, если интересно можете глянуть.
https://github.com/alexeyk500/ToolTipComponent/tree/onlyCSS
Что заметил из недостатков:
1) Нет возможности реализовать время задержки перед появлением тултипа. (разве что писать кастомную временную функцию вместо стандартной ease.
2) Блок :after присутствует в ReactDom и увеличивает его размер, хоть и скрыт свойством hidden.
3) Не такие широкие возможности для анимации появления и исчезновения тултипа, как при использовании CSSTransition. В моем примере - onlyCSS, анимация работает только в одну сторону - подсказка опускается на hover и исчезает при когда указатель мыши покидает целевой элемент, анимацию дальнейшего погружения и исчезновения тултипа уже реализовать не удалось.
4) Отсутствует возможность организовать условное появление тултипа (например для неактивных кнопок).

1) CSS Transition вы можете заменить на CSS Animation и тогда у вас будет уже более полный контроль анимации более гибкий
2) no comments - css псевдоэлементы норма в 2023
3) см пункт 1 CSS анимации все еще доступны
4) на самом деле не отсутствует, вы можете менять visibility не только по .elem:hover но и по .elem.-showtooltip - организовав сверху логику с добавлением удалением класса, также :hover можете и на :disabled поменять и показывать подсказку только при :disabled :readonly и тп состояний в общем только css селекторами тут вы ограничены
надеюсь мой опыт вам пригодился
Выглядит конечно устрашающе. Понятно что реакт не для сайтов-визиток, тем не менее вот это вот все чтобы сделать тултип... )
Самый плохой подход для реализации тултипов. Это постоянные проблемы с позиционированием, т.к тултип является оберткой. Также в дев тулзах он показывается выше и постоянно находится в VDOM.
Адекватная реализация тултипов это использовать либо нативный title атрибут и все остальные прелести хмтл, либо через реф на элемент и портал, либо чистый цсс
React, всплывающие подсказки (tooltips), для самых маленьких