Могу ли я установить размер элемента в соответствии с его потенциальным содержимым, а не с его фактическим содержимым? - PullRequest
1 голос
/ 25 марта 2019

Рассмотрим эту панель кнопок:

body {text-align: right;}
<button>Save</button>
<button>Cancel</button>
<button>Delete</button>

Теперь предположим, что содержимое последней кнопки изменяется:

body {text-align: right;}
<button>Save</button>
<button>Cancel</button>
<button>Click me again to confirm deletion</button>

Как видите, это изменение в самой правой кнопке сработало для перемещения всех кнопок слева от нее.

Чтобы избежать этого, я бы хотел, чтобы исходный размер кнопки соответствовал большему из двух возможных ее вариантов.

Конечно, я могу попытаться «достичь» этого разными способами. Самым простым и уродливым является экспериментировать, какой ширины требует больший контент, и «жестко закодировать» его:

body {text-align: right;}

#del {display: inline-block; width: 220px;}
<button>Save</button>
<button>Cancel</button>
<button id="del">Delete</button>

Однако я считаю, что это не решение, потому что нельзя гарантировать, что эта ширина будет одинаковой для всех остальных. Если кто-то использует странный шрифт, использует увеличение текста, просматривает сайт на мобильном телефоне или что-то еще, то я полагаю, что установка ширины кнопки в жестко заданном значении может привести к странным результатам.

Другим способом, я полагаю, было бы: (а) Изначально поместить более длинный текст в кнопку (б) Получить ширину кнопки с помощью JavaScript и сохранить ее (в) Поместить фактический, более короткий текст в кнопку и установить ее ширина к этому значению. Однако, на мой взгляд, это выглядит как ужасный взлом и перебор.

Каково каноническое решение подобных проблем?

1 Ответ

1 голос
/ 25 марта 2019

Я бы рассмотрел атрибут данных, чтобы добавить оба текста с использованием псевдоэлементов, а затем контролировать непрозрачность, чтобы скрыть / показать их:

div {
  text-align: right;
}

#del {
  display: inline-block;
  position: relative
}

#del:before {
  content: attr(data-text);
  position:absolute;
  left:0;
  right:0;
  top:1px; /*there is 1px default padding */
  text-align:center;
}

#del:after {
  content: attr(data-alt);
  opacity:0;
}


#del:hover::before {
   opacity:0;
}
#del:hover::after {
   opacity:1;
}
<div><button>Save</button><button>Cancel</button><button data-text="Delete" data-alt="Click me again to confirm deletion" id="del"></button></div>

Вам просто нужно знать, какой из них будет шире, чтобы он оставался в потоке, чтобы определить ширину и сделать другой position:absolute.

Вы также можете хранить основной текст внутри:

div {
  text-align: right;
  font-size:14px;
}

#del {
  display: inline-block;
  position: relative;
}

#del span {
  content: attr(data-text);
  position:absolute;
  left:0;
  right:0;
  top:1px; /*there is 1px default padding */
  text-align:center;
}

#del:after {
  content: attr(data-alt);
  opacity:0;
}


#del:hover span {
   opacity:0;
}
#del:hover::after {
   opacity:1;
}
<div><button>Save</button><button>Cancel</button><button  data-alt="Click me again to confirm deletion" id="del"><span>Delete</span></button></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...