Как стать автором
Обновить

Комментарии 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 считается как клик и замирает в положении наведения.

Как читается ховер я в курсе)

Тут скорее вопрос про onMouseEnter и onMouseLeave

Через 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 атрибут и все остальные прелести хмтл, либо через реф на элемент и портал, либо чистый цсс

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории