Текст в пользовательских кнопках случайным образом не центрируется по вертикали - PullRequest
5 голосов
/ 07 апреля 2019

У меня есть форма, в которой я использую несколько кнопок «плюс» и «минус» для добавления новых элементов в форму по мере необходимости пользователем. Я использовал собственный стиль кнопок. Я использовал этот сайт, чтобы получить необходимые CSS, чтобы убедиться, что текст центрирован. Но, похоже, это работает только в некоторых случаях кнопки.

function unhide(id) {
  var myForm = document.forms.mrform;
  var myControls = myForm.elements[id.concat('[]')];
  for (var i = 0; i < myControls.length; i++) {
    var aControl = myControls[i];
    if ($(aControl).is(':hidden')) {
      $("#".concat(id.concat(i+1).replace(/ /g, "_"))).show();
	  break;
    }
  }
}

function hide(id) {
  var myForm = document.forms.mrform;
  var myControls = myForm.elements[id.concat('[]')];
  for (var i = myControls.length; i > 0 ; i--) {
    var aControl = myControls[i];
    if ($(aControl).is(':visible')) {
      $("#".concat(id.concat(i+1).replace(/ /g, "_"))).hide();
	  break;
    }
  }
}
.pmbutton {
  background-color: greenyellow;
  border: none;
  color: black;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 10px;
  height: 17px;
  width: 17px;
  padding: 0px;
  margin: 0px 0px 0px 4px;
  vertical-align: middle;
  line-height: 17px;
  box-sizing: border-box;
}

.hideme {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id='mrform' action='report_generator.php' method='post' autocomplete='off' onkeypress='return event.keyCode != 13;'>
<table class='subform'>
  <tr id='Objective_Item1'><td class='prompt text'>Objective Item #1 :</td><td class='input'><input class='inputbox text' type='text' name='Objective Item[]'><button type='button' class='pmbutton' onclick='unhide("Objective Item")'>+</button><button type='button' class='pmbutton' onclick='hide("Objective Item")'>-</button></td></tr>
  <tr id='Objective_Item2' class='hideme'><td class='prompt text'>Objective Item #2 :</td><td class='input'><input class='inputbox text' type='text' name='Objective Item[]'></td></tr>
  <tr id='Objective_Item3' class='hideme'><td class='prompt text'>Objective Item #3 :</td><td class='input'><input class='inputbox text' type='text' name='Objective Item[]'></td></tr>
  <tr id='Objective_Item4' class='hideme'><td class='prompt text'>Objective Item #4 :</td><td class='input'><input class='inputbox text' type='text' name='Objective Item[]'></td></tr>
  <tr id='Objective_Item5' class='hideme'><td class='prompt text'>Objective Item #5 :</td><td class='input'><input class='inputbox text' type='text' name='Objective Item[]'></td></tr>
  <tr id='Objective_Item6' class='hideme'><td class='prompt text'>Objective Item #6 :</td><td class='input'><input class='inputbox text' type='text' name='Objective Item[]'></td></tr>
  <tr id='Objective_Item7' class='hideme'><td class='prompt text'>Objective Item #7 :</td><td class='input'><input class='inputbox text' type='text' name='Objective Item[]'></td></tr>
  <tr id='Objective_Item8' class='hideme'><td class='prompt text'>Objective Item #8 :</td><td class='input'><input class='inputbox text' type='text' name='Objective Item[]'></td></tr>
  <tr id='Objective_Item9' class='hideme'><td class='prompt text'>Objective Item #9 :</td><td class='input'><input class='inputbox text' type='text' name='Objective Item[]'></td></tr>
  <tr id='Objective_Item10' class='hideme'><td class='prompt text'>Objective Item #10 :</td><td class='input'><input class='inputbox text' type='text' name='Objective Item[]'></td></tr>
</table>
</form>

Функциональность в порядке, но в некоторых случаях текст не центрируется по центру кнопки, а в других - IS. Кажется, один пиксель отключен в случайных кнопках. Я видел это в Firefox и Chrome (что, кажется, хуже). Любые предложения относительно причины?

Редактировать: добавление изображения нескольких изображений одной кнопки на одной странице сайта. Единственное свойство, которое я изменяю между некоторыми из них, это цвет фона. Кажется, что вертикальное и горизонтальное выравнивание различаются.

Button Renderings

Additional Button renderings

Ответы [ 5 ]

6 голосов
/ 20 апреля 2019

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

TL; DR

На мой взгляд, самым безопасным подходом было бы создание изображений + и и использование их вместо кнопок.


Как работают шрифты

Чтобы ответить на ваш вопрос, вам нужно знать, как сначала работают шрифты.

Каждый символ шрифта помещается в свой собственный контейнер. В традиционном металлическом типе этот контейнер был фактическим металлическим блоком каждого персонажа. Высота каждой части символа была одинаковой, что позволяло аккуратно расставлять символы по строкам и блокам. Это пространство называется «em-space» и происходит от ширины заглавного M символа. Это было сделано для того, чтобы пропорции этой буквы были квадратными.

В цифровом типе em-space определяется следующим образом:

  • В шрифте OpenType он обычно устанавливается на 1000 единиц.
  • В шрифтах TrueType условно это степень два, обычно равная 1024 или 2048 единицам.

Когда шрифт используется для установки типа, em масштабируется до желаемого размера точки.

Каждый символ в вашем шрифте также имеет следующие элементы:

  • Базовая линия - это линия, определяющая основание символа. За некоторыми исключениями, такими как g и q символы не пересекают базовую линию.
  • Высота колпачка - это линия, которая определяет верх заглавной буквы. Обычно это плоские буквы, такие как H или I, тогда как O или A могут перескочить.
  • X-высота - высота строчной буквы. Как правило, это высота буквы x в шрифте, отсюда и название.
  • Ascender - это часть буквы в нижнем регистре, которая выше, чем x-высота шрифта. Подумайте о b и d символах.
  • Descender - это часть буквы, которая простирается ниже базовой линии шрифта. Я уже упоминал g и q.

Все эти элементы содержатся внутри em-space.

Теперь, что происходит, когда вы пытаетесь уменьшить шрифт до 10 пикселей (в зависимости от настроек font-size: 10px;). Если вы не изменили настройки браузера, размер шрифта браузера по умолчанию составляет 16 пикселей (1 em = 2048 единиц для Times New Roman, который вы, похоже, используете).

Но Times New Roman использует 1825 подъема и 443 спуска, что составляет 2268 единиц в 2048 единицах квадрата на Windows. Mac, кажется, использует значения HHead, которые одинаковы для Times New Roman. Вот скриншот, показывающий эти значения:

Times New Roman font info

Что это значит? Это означает, что при указании font-size: 10px фактический размер Times New Roman будет совершенно другим. Если я прав в своих расчетах, то оно будет 11.07421875 округлено до 11px (уже "ой", верно?)

line-height и vertical-align

Хорошо, затем, когда ваш button отображается на экране, он может состоять из множества строк в зависимости от ширины. Каждая строка состоит из одного или нескольких встроенных элементов (например, span элементов с различными настройками шрифта) и называется строковым блоком. Высота линейного бокса зависит от роста его детей. Браузер вычисляет высоту для каждого встроенного элемента и выбирает самый высокий дочерний элемент в качестве «шаблона» для линейного блока. Это гарантирует, что вы видите все символы на вашем экране, когда элемент отображается.

Это поведение отличается от Word или Photoshop. В этих программах line-height не основано на линейном блоке. Вместо этого это расстояние между базовыми линиями. Но в CSS это не так. В css ваш line-height - это ваш line-box.

Следует отметить, что CSS не указывает значение по умолчанию line-height. Значение по умолчанию normal:

Сообщает пользовательским агентам установить «разумное» значение для используемого значения на основе шрифта элемента. Значение имеет то же значение, что и. Мы рекомендуем использовать значение для «нормального» в диапазоне от 1,0 до 1,2. Вычисленное значение является «нормальным».

А это спецификации для vertical-align:

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

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

Действительно

Я проверил + и - в программном обеспечении для редактирования шрифтов, и это выглядит так:

Plus and Hyphen in Times New Roman

Хотя + кажется симметричным, он все еще немного опущен внутри своей области содержимого; и - понижается к базовой линии. Так что ответ на - очевиден. Исходя из всего, что я исследовал и опубликовал выше - вы не сможете центрировать его по вертикали, оно всегда будет немного ниже. На маленьких размерах шрифта это может быть пиксель или два; на большом размере шрифта вы увидите это сразу.

Обратите внимание, что -, который вы привыкли печатать (верхняя правая клавиша на цифровой клавиатуре или правая клавиша 0) - это не минус, а hyphen. Минус и дефис выглядят по-разному: против -.

Будет ли − (minus) выглядеть по-другому? Это, безусловно, имеет больше симметрии к нему:

Plus and Minus in Times New Roman

Здесь вы можете видеть более четко, что + и − (minus) находятся ближе к базовой линии.

Флексбоксы как возможное решение?

Давайте посмотрим на flexbox. Когда вы определяете display: flex, генерируется окно с именем flex container. Дочерние потоки гибкого контейнера называются flex items и располагаются внутри гибких линий.

В отличие от блочной и встроенной компоновки, расчеты компоновки которой смещены к блоку и линейным направлениям потока, гибкая компоновка смещена к направлениям прогиба.

flex container and flex items

Теперь гибкие линии, кроме линейных блоков, работают по-другому:

Как только содержимое разбито на строки, каждая строка раскладывается независимо; гибкая длина и свойства justify-content и align-self учитывают только элементы в одной строке за раз.

В многострочном гибком контейнере (даже в одном, содержащем только одну строку) размер креста каждой строки - это минимальный размер, необходимый для размещения гибких элементов в строке (после выравнивания из-за align-self), и линии выровнены внутри контейнера flex с помощью свойства align-content. В гибком контейнере, состоящем из одной строки, размер поперечного сечения строки - это размер поперечного сечения гибкого контейнера, а выравнивание содержимого не оказывает влияния. Основной размер строки всегда совпадает с основным размером поля содержимого гибкого контейнера.

Итак, когда вы определяете align-items: center,

Поле для полей гибкого элемента центрируется по оси креста в пределах линии.

И, наконец, , если я правильно понял спецификацию , когда вы указываете align-items: center, базовая линия генерируется динамически, что позволяет вам фактически идеально центрировать + и .

В заключение

Вы должны использовать flexbox и использовать div, а не button, так как button ведет себя иначе (я бы приветствовал задокументированное предложение, почему). Даже если вы укажете огромные числа (например, width и height до 400px и font-size до 750px), вы увидите небольшое смещение вниз. Но на небольших размерах все, кажется, работает отлично.

На мой взгляд, самым безопасным подходом было бы создание изображений + и и использование их вместо кнопок.


Источники Я исследовал:

Приложение для отображения информации о шрифте - https://fontforge.github.io/en-US/

2 голосов
/ 20 апреля 2019

Я полагаю, что это может быть из-за самого элемента кнопки:

При размещении + внутри отдельного диапазона и выравнивании диапазона идеально по центру,
с помощью флексбоксов, + все еще не совсем в центре.Когда я делаю то же самое с элементом div,
+ имеет точно центрированный.

Проверьте эту скрипку , чтобы понять, что я имею в виду.
Поэтому я рекомендую использовать div с событием click вместо кнопки.

Также, если вы хотите иметь знак минуса, который выровнен по вертикали на той же высоте, что и плюс,
вам следует использовать &minus; вместо - внутри вашего элемента.

1 голос
/ 21 апреля 2019

Возможно, вы могли бы сделать вместо жестко закодированных height и width, используйте padding для пробела. Если font-size равно 10px, тогда просто дайте ему отступ 4px

1 голос
/ 21 апреля 2019

Вам необходимо указать семейство шрифтов в .pmbutton,

, вы можете выбрать широко используемый веб-безопасный шрифт или вы можете объявить свой собственный font-face

.pmbutton {
   font-family:arial;
}
0 голосов
/ 21 апреля 2019

Как я понимаю, вам нужно поставить свои ценности в центральное положение Согласно HTML-коду, который вы разместили выше Вы не можете разместить свой текст в центре, если вы не выполните следующие действия:

<td class = "test" align = "center">+<td>

Вы должны использовать align = "center", чтобы получить текст в центральном положении и не использовать CSS, для этого он не будет работать, просто используйте его, как указано выше Теперь вам нужно разместить текст по центру Этот шаг может быть достигнут с помощью CSS

.test { padding-top = 2px; padding-bottom = 2px;}

Как указано выше в CSS, вертикальное положение регулируется отступом.

Другой способ, если не работать с HTML5

Использовать span внутри тега

<td class ="test"><span>+</span></td>

Тогда используйте CSS

.test > span { padding-top = 2px; padding-bottom = 2px; padding-right = 2px padding-left = 2px;}

Обновление

Посмотрите на случай, если вы спросите о Mac OS и iPhone, а также о перезагрузке этого устройства, так что вот мой совет Не используйте теги td с этими устройствами, они не будут работать нормально, и это связано с разработкой приложений, а не для самих устройств. Если вы используете Firefox на iPhone, он может нормально работать Так что используйте этот тип тегов Пример

<dl>
<dt>Coffee</dt>
<dd>Black hot drink</dd>
<dt>Milk</dt>
<dd>White cold drink</dd>
</dl>

дт лучше чем тд

Причина:

Возможные причины такого поведения Я ищу и спрашиваю некоторых друзей, почему это может происходить в некоторых браузерах, а в других нет? И я получил такой вывод:

Это потому, что иногда веб-просмотр Safari увеличивает текст автоматически, потому что это хорошая идея.

Чтобы отключить это, используйте этот стиль CSS:

-webkit-text-size-adjust:none;

Теперь ваши персонажи должны отображаться без перерыва.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...