Как сделать знак плюс в точном центре круга на css?
Добрый день. Возникла следующая проблема. Требовалось создать значок «плюс в кружке», где плюс находится точно в центре кружка. При этом сам плюс является after-псевдоэлементом для одного div-а.
Код псевдоэлемента:
content: '+'; display: flex; position: absolute; z-index: 5; font-size: 35px; font-weight: 400; color: white; background-color: #1ED4B3; border: solid 1px #1ED4B3; border-radius: 50%; width: 45px; height: 45px; align-items: center !important; flex-direction:column !important; justify-content: space-evenly !important;
Всё работает нормально для десктопных версий, но на всех мобильных браузерах проблема в том, что знак плюса в кружке сдвинут кверху, а не находится по центру.
Пробовал уже использовать знак заглавного плюса U+FF0B , пробовал использовать justify-content: space-between , justify-content: space-around , justify-content: center , align-items: stretch .
Есть идеи, из-за чего такое может быть и как это можно исправить?
Более полный код (включая класс div-а , к которому привязан псевдоэлемент):
.div__after < display: flex; flex-direction: column; align-content: center; align-items: center; &::after< content: '+'; display: flex; position: absolute; z-index: 5; font-size: 35px; font-weight: 400; color: white; background-color: #1ED4B3; border: solid 1px #1ED4B3; border-radius: 50%; width: 45px; height: 45px; align-items: center !important; flex-direction:column !important; justify-content: space-evenly !important; @media (--xs-viewport)< top: calc(100% - 10px); >@media (--md-viewport) < top: 25%; left: calc(100% - 10.5px); >@media (--lg-viewport) < left: calc(100% - 7.5px); >> >
- Вопрос задан 27 июн.
- 246 просмотров
Комментировать
Решения вопроса 1

Виталий Першин @Get-Web Куратор тега CSS
Front-End Developer

Сделайте плюс не шрифтом, а блоком из горизонтальной и вертикальной линий, потому что у шрифтов полно свойств:
Чему к примеру равна горизонтальная линия вашего шрифтового плюса при размере 35px? Если у вас размер блока 45px, то линия должна быть так же с нечетным размером ровно 1px или 3px, или 5px в любом другом случае (1.2px, 3.6px, 4px) браузер начнет смещать ваш плюс вверх и вниз, что вы и наблюдаете.
Если же блок будет с четным значением, например 44px, тогда, чтобы плюс стал по центру у него должен быть размер 2px,4px и т.д..
Шрифты для такой задачи не подходят, тем более с изменением шрифта изменится и его центр.
Ответ написан 27 июн.
Нравится 4 4 комментария
vladimirir @vladimirir Автор вопроса
Спасибо! Прошу прощения за, возможно, нубский вопрос, но как я смогу две пересекающиеся черты в content вставить?
Сделать символ плюса в CSS
У меня есть приведенный ниже код CSS, который дает символ + , но не соответствует дизайну, в основном он должен быть тонким.
.plus

Символ должен выглядеть так : Любой другой стиль мне тоже подходит, но лучше сделать как на снимке. Свободный перевод вопроса Make plus symbol in CSS от участника @Sharath.
Отслеживать
Alexandr_TT
задан 16 фев 2021 в 8:30
Alexandr_TT Alexandr_TT
109k 23 23 золотых знака 111 111 серебряных знаков 372 372 бронзовых знака
ассоциация:stackoverflow.com/q/55281672/7394871
16 фев 2021 в 8:31
6 ответов 6
Сортировка: Сброс на вариант по умолчанию
Используйте несколько background , как показано ниже:
.plus < display:inline-block; width:50px; height:50px; background: linear-gradient(#fff,#fff), linear-gradient(#fff,#fff), #000; background-position:center; background-size: 50% 2px,2px 50%; /*thickness = 2px, length = 50% (25px)*/ background-repeat:no-repeat; >.alt < background: linear-gradient(#000,#000), linear-gradient(#000,#000); background-position:center; background-size: 50% 2px,2px 50%; /*thickness = 2px, length = 50% (25px)*/ background-repeat:no-repeat; >.radius

А вот вариант с прозрачностью:
.plus < width:50px; height:50px; display:inline-block; background: linear-gradient(#000,#000) top left, linear-gradient(#000,#000) top right, linear-gradient(#000,#000) bottom left, linear-gradient(#000,#000) bottom right; background-size: calc(50% - 1px) calc(50% - 1px); /*thickness = 2px (2*1px) */ background-repeat:no-repeat; border:10px solid #000; /*length = 30px (50px - 2x10px) */ box-sizing:border-box; >.radius
body

Мы можем добавить переменную CSS, чтобы легко контролировать общую форму:
.plus < --t:2px; /* Thickness */ --l:40px; /* size of the symbol */ --s:10px; /* space around the symbol */ --c1:#fff; /* Plus color*/ --c2:#000; /* background color*/ display:inline-block; width:var(--l); height:var(--l); padding:var(--s); box-sizing:border-box; /*Remove this if you don't want space to be included in the size*/ background: linear-gradient(var(--c1),var(--c1)) content-box, linear-gradient(var(--c1),var(--c1)) content-box, var(--c2); background-position:center; background-size: 100% var(--t),var(--t) 100%; background-repeat:no-repeat; >.radius

Отслеживать
ответ дан 16 фев 2021 в 8:30
Alexandr_TT Alexandr_TT
109k 23 23 золотых знака 111 111 серебряных знаков 372 372 бронзовых знака
body .plus_one, .plus_two < width: 50px; height: 50px; margin-right: 10px; background-color: black; >.plus_one:before, .plus_two:before < content: "+"; display: flex; flex-direction: row; align-items: center; justify-content: center; height: 50px; width: 50px; font-size: 80px; line-height: 105px; text-align: center; color: white; >.plus_one::before .plus_two::before
Можно добавить и любую анимацию по первому же требованию. Например, немного так поэкспериментировать:
body < display: flex; justify-content: center; align-items: center; width: 100%; height: 50vh; overflow: hidden; >.body < z-index: -1; position: absolute; top: 0; left: 0; width: 100%; height: 100vh; >.plus_animate < width: 80px; height: 80px; margin-right: 10px; background-color: black; >.plus_animate:before < content: "+"; display: flex; flex-direction: row; align-items: center; justify-content: center; height: 80px; width: 80px; font-size: 120px; line-height: 105px; text-align: center; color: white; >.plus_animate:before < font-family: serif; font-weight: normal; >/*Анимация*/ .body < background: white; animation: body_a 1s forwards ease-in-out; >.plus_animate:hover~.body < background: black; animation: body_b 1s forwards ease-in-out; >@keyframes body_a < 0% < background: black; >100% < background: white; >> @keyframes body_b < 0% < background: white; >100% < background: black; >> .plus_animate < transform: rotate(0deg); border-radius: 0; background-color: black; animation: plus_a 1s forwards ease-in-out; >.plus_animate:hover < transform: rotate(1440deg); border-radius: 100%; background-color: white; animation: plus_b 1s forwards ease-in-out; >@keyframes plus_a < 0% < transform: rotate(1440deg); border-radius: 100%; background-color: white; >100% < transform: rotate(0deg); border-radius: 0; background-color: black; >> @keyframes plus_b < 0% < transform: rotate(0deg); border-radius: 0; background-color: black; >100% < transform: rotate(1440deg); border-radius: 100%; background-color: white; >> .plus_animate:before < font-family: serif; font-weight: normal; transform: rotate(0deg); color: white; animation: plus_before_a 1s forwards ease-in-out; >.plus_animate:hover:before < font-family: sans-serif; font-weight: bold; transform: rotate(45deg); color: black; animation: plus_before_b 1s forwards ease-in-out; >@keyframes plus_before_a < 0% < font-family: sans-serif; font-weight: bold; transform: rotate(45deg); color: black; >1%, 100% < font-family: serif; font-weight: normal; transform: rotate(0deg); color: white; >> @keyframes plus_before_b < 0% < font-family: serif; font-weight: normal; transform: rotate(0deg); color: white; >10% < color: black; >90% < font-family: serif; font-weight: normal; transform: rotate(0deg); color: black; >100% < font-family: sans-serif; font-weight: bold; transform: rotate(45deg); color: black; >>
Или совсем не экспериментировать:
body .plus_animate < width: 50px; height: 50px; margin-right: 10px; overflow: hidden; background-color: black; >.plus_animate:before < content: "+"; display: flex; flex-direction: row; align-items: center; justify-content: center; height: 50px; width: 50px; font-size: 80px; text-align: center; color: white; font-family: serif; font-weight: normal; >.plus_animate:hover:before @keyframes plus < 0% 50% 90% 100% >
CSS решения. Фиксированный блок плюс адаптивный блок.
В данной статье поговорим об одной из базовых задач в вёрстке — создании фиксированного и адаптивного блоков; приведём решение данной задачи, а также разберём основные преимущества и недостатки описываемых решений.
В данной статье будем рассматривать два случая:
- old style — решение, которое должно работать в браузере IE9 и выше
- new style — использование flex’ов, а также большей части CSS3, которые поддерживает большинство современных браузеров.
Есть еще feature style — CSS grid, но это уже выходит за рамки статьи.
Одна из самых популярных задач в вёрстке — блок фиксированной ширины плюс адаптивный блок.
Old style
Для решения задачи в старом стиле используется следующий подход:
- Создаётся блок (div) и два дочерних блока
- Фиксированный блок идёт первым, которому задаётся фиксированная ширина width: 10rem и свойство float: left (или right, в зависимости от требуемого расположения).
- Адаптивный блок получает свойство float: none , а также отступ равный ширине фиксированного блока margin-left: 10rem (можно задать отступ больше, чем фиксированный блок, чтобы между фиксированным и адаптивным блоком была пустое расстояние).
- Если высота адаптивного блока может быть меньше высоты фиксированного блока, то тогда необходимо у родительского блока поставить явное автовыравнивание высоты (очистка плавающих блоков) с помощью overflow: hidden , или неявно с помощью утилиты clearfix;
В данном примере использовались дополнительные стили для создания превью:
Для решения данной проблемы, воспользуемся утилитой clearfix из bootstrap:
Отметим, что overflow: hidden привёл к тому же результату с одним лишь исключением, что при всплывающих блоках внутри родительского, контент будет обрезаться.
Преимущества:
- Работает во всех популярных браузерах.
Отметим, что для браузеров каменного века (IE ≤ 8), делается отдельное решение, которое не является частью основного проекта.
Недостатки:
- Невозможность лаконичной реализации дополнительной возможности — одинаковая высота фиксированного и адаптивного блока средствами CSS.
Лучшим решением в старом подходе для данной задачи является создание микро скрипта, который следит за изменением ширины блоков и обновляет высоту блоков.
New style
Основным решением в данный момент является использование flex.
- Создать родительский блок и задать display: flex
- Для фиксированного блока задать свойство display: block и ширину width: 10rem
- Для адаптивного блока задать свойство flex: 1, которое заставляет блок занимать всё доступное пространство
В данном случае, реализация будет следующей:
Если добавить контент, то можно увидеть, что структура ведёт себя ожидаемо.
Преимущества:
- Порядок элементов является правильным;
- Блоки получают общую высоту, делая колонки одинаковой высоты без какой-либо манипуляции;
- Наезды на другие блоки в данном решении отсутствуют в сравнении со старым подходом.
Недостатки:
- Не работает в старых браузерах, которые не поддерживают flex.
Демо
Небольшая демонстрация выше приведенных решений:
Резюме
В данной статье рассмотрели классическую задачу верстки с фиксированным и адаптивным блоком.
Привели примеры реализации данной задачи в двух вариантах:
- old style — решение, поддерживаемое во всех популярных браузерах;
- new style — решение, для всех современных браузеров.
Разобрали нюансы, которые есть в старом подходе.
Спасибо за внимание!
Исходники
Все исходники находятся на github, в репозитории:
Плюс и минус для поля input

Небольшой скрипт на jQuery, который при нажатии на соотвествующую кнопку, прибавляет и отнимает единичку в текстовом поле.
Также в этой теме есть несколько вариантов оформления этих кнопок.
Пример:
(вид немного отличается из-за стилей сайта)
HTML:
Где атрибут data-max-count — максимальное значение.
jQuery:
// Убавляем кол-во по клику
$ ( ‘.quantity_inner .bt_minus’ ) . click ( function ( ) <
let $ input = $ ( this ) . parent ( ) . find ( '.quantity' ) ;
let count = parseInt ( $ input . val ( ) ) - 1 ;
count = count < 1 ? 1 : count ;
$ input . val ( count ) ;
// Прибавляем кол-во по клику
$ ( '.quantity_inner .bt_plus' ) . click ( function ( ) <
let $ input = $ ( this ) . parent ( ) . find ( '.quantity' ) ;
let count = parseInt ( $ input . val ( ) ) + 1 ;
count = count > parseInt ( $ input . data ( ‘max-count’ ) ) ? parseInt ( $ input . data ( ‘max-count’ ) ) : count ;
$ input . val ( parseInt ( count ) ) ;
// Убираем все лишнее и невозможное при изменении поля
$ ( ‘.quantity_inner .quantity’ ) . bind ( «change keyup input click» , function ( ) <
if ( this . value . match ( /[^0-9]/g ) ) <
this . value = this . value . replace ( /[^0-9]/g , '' ) ;
if ( this . value == "" ) <
this . value = 1 ;
if ( this . value > parseInt ( $ ( this ) . data ( ‘max-count’ ) ) ) <
this . value = parseInt ( $ ( this ) . data ( 'max-count' ) ) ;
Скрипт работает таким образом, что в текстовое поле input можно вводить только цифры. Если введено некорректное значение или оно отсутствует, то в поле вставляется единица. Если введено значение больше максимального, то в поле ставится максимально возможное.
Оформление:
Во всех примерах используется jQuery приведенный выше
.quantity_inner * < box-sizing : border-box ; .quantity_inner < display : flex ; justify-content : center ; .quantity_inner .bt_minus, .quantity_inner .bt_plus, .quantity_inner .quantity < color : #BFE2FF ; height : 40px ; width : 40px ; padding : 0 ; margin : 10px 2px ; border-radius : 10px ; border : 4px solid #BFE2FF ; background : #337AB7 ; cursor : pointer ; outline : 0 ; box-shadow : 0 2px 5px rgba ( 0,0,0,0.2 ) , 0 4px 6px rgba ( 0,0,0,0.2 ) ; .quantity_inner .quantity < width : 50px ; text-align : center ; font-size : 22px ; color : #FFF ; font-family : Menlo,Monaco,Consolas,"Courier New",monospace ; .quantity_inner .bt_minus svg, .quantity_inner .bt_plus svg < stroke : #BFE2FF ; stroke-width : 4 ; transition : 0.5s ; margin : 4px ; .quantity_inner .bt_minus:hover svg, .quantity_inner .bt_plus:hover svg < stroke : #FFF ; .quantity_inner * < box-sizing : border-box ; .quantity_inner < display : inline-flex ; border-radius : 26px ; border : 4px solid #337AB7 ; .quantity_inner .bt_minus, .quantity_inner .bt_plus, .quantity_inner .quantity < height : 40px ; width : 40px ; padding : 0 ; background : transparent ; cursor : pointer ; outline : 0 ; .quantity_inner .quantity < width : 50px ; text-align : center ; font-size : 30px ; font-weight : bold ; color : #000 ; font-family : Menlo,Monaco,Consolas,"Courier New",monospace ; .quantity_inner .bt_minus svg, .quantity_inner .bt_plus svg < stroke : #337AB7 ; stroke-width : 4 ; transition : 0.5s ; margin : 10px ; .quantity_inner .bt_minus:hover svg, .quantity_inner .bt_plus:hover svg < stroke : #000 ; .quantity_inner * < box-sizing : border-box ; .quantity_inner < display : inline-flex ; border-radius : 26px ; border : 4px solid #337AB7 ; position : relative ; background : #FFF ; .quantity_inner .bt_minus, .quantity_inner .bt_plus, .quantity_inner .bt_buy, .quantity_inner .quantity < height : 40px ; width : 40px ; padding : 0 ; background : #FFF ; cursor : pointer ; outline : 0 ; border-radius : 26px ; .quantity_inner .bt_buy < background : #337AB7 ; width : 90px ; height : 48px ; position : absolute ; right : -70px ; border-radius : 0 26px 26px 0 ; border : 4px solid #337AB7 ; .quantity_inner .quantity < width : 60px ; text-align : center ; font-size : 30px ; font-weight : bold ; color : #000 ; font-family : Menlo,Monaco,Consolas,"Courier New",monospace ; .quantity_inner .bt_minus svg, .quantity_inner .bt_plus svg, .quantity_inner .bt_buy svg < stroke : #337AB7 ; stroke-width : 4 ; transition : 0.5s ; margin : 10px ; fill : none ; height : 20px ; width : 20px ; .quantity_inner .bt_buy svg < stroke : #BFE2FF ; position : relative ; .quantity_inner .bt_buy:hover svg < stroke : #FFF ; .quantity_inner .bt_minus:hover svg, .quantity_inner .bt_plus:hover svg < stroke : #000 ; .quantity_inner * < box-sizing : border-box ; .quantity_inner < display : inline-flex ; border : 4px solid #337AB7 ; position : relative ; .quantity_inner .bt_minus, .quantity_inner .bt_plus, .quantity_inner .quantity < height : 40px ; width : 40px ; padding : 0 ; background : transparent ; cursor : pointer ; outline : 0 ; .quantity_inner .bt_minus, .quantity_inner .bt_plus < position : absolute ; height : 20px ; width : 20px ; right : 10px ; .quantity_inner .bt_plus < .quantity_inner .bt_minus < bottom : 2px ; .quantity_inner .quantity < width : 60px ; text-align : center ; font-size : 30px ; font-weight : bold ; color : #000 ; margin-right : 30px ; font-family : Menlo,Monaco,Consolas,"Courier New",monospace ; .quantity_inner .bt_minus svg, .quantity_inner .bt_plus svg < stroke : #337AB7 ; stroke-width : 4 ; transition : 0.5s ; fill : none ; .quantity_inner .bt_minus:hover svg, .quantity_inner .bt_plus:hover svg < stroke : #000 ; .quantity_inner * < box-sizing : border-box ; .quantity_inner < display : inline-flex ; border : 6px solid #BFE2FF ; position : relative ; border-radius : 50% 0 ; height : 100px ; width : 120px ; background : #FFF ; margin-top : 30px ; .quantity_inner .bt_minus, .quantity_inner .bt_plus, .quantity_inner .quantity < height : 40px ; width : 40px ; padding : 0 ; background : transparent ; cursor : pointer ; outline : 0 ; position : absolute ; .quantity_inner .bt_minus, .quantity_inner .bt_plus < height : 40px ; width : 40px ; right : 6px ; .quantity_inner .bt_minus < .quantity_inner .bt_buy < position : absolute ; background : #337AB7 ; padding : 0 ; border : 6px solid #BFE2FF ; left : -20px ; border-radius : 50% ; height : 70px ; width : 70px ; outline : 0 ; transition : 0.5s ; .quantity_inner .bt_buy:hover < cursor : pointer ; border : 6px solid #337AB7 ; .quantity_inner .bt_buy:hover svg < stroke : #FFF ; .quantity_inner .quantity < width : 60px ; bottom : 6px ; text-align : center ; font-size : 42px ; font-weight : bold ; color : #000 ; margin-right : 30px ; font-family : Menlo,Monaco,Consolas,"Courier New",monospace ; .quantity_inner .bt_minus svg, .quantity_inner .bt_plus svg < stroke : #337AB7 ; stroke-width : 2 ; transition : 0.5s ; fill : none ; .quantity_inner .bt_buy svg < stroke : #BFE2FF ; stroke-width : 3 ; transition : 0.5s ; fill : none ; width : 26px ; height : 26БзЮБ/зЮpx ; .quantity_inner .bt_minus:hover svg, .quantity_inner .bt_plus:hover svg < stroke : #000 ; Нравится 18 В закладки
- Опубликовано: 26.10.2020
- Рубрики: Формы
- Метки: CSS, jQuery, Авторское
- 16042 просмотра
Смотрите также:

Варианты оформления jQuery UI Slider
Несколько вариантов оформления и добавление различных функций к ползунку диапазонов jQuery UI Slider

Ползунок диапазонов jQuery UI Slider
Настройка, события, методы, вывод данных и классы ползунка диапазонов jQuery UI Slider
![]()
Радиокнопки с иконками
Стилизация переключателей radio с использованием иконочных шрифтов или картинок
Добавить комментарий:
Ваш комментарий отправлен!
Комментарии:
dumb: 05.07.2023 в 20:48
а как полученный результат (количество) дальше для обработки php передать?
Alexander: 11.07.2023 в 10:44
Как обычно, у нас есть input и его value
Павел: 21.02.2023 в 18:58
может кому понадобится, я переписал jquery код в нативный js
// Убавляем кол-во по клику document.querySelectorAll('.quantity_inner .bt_minus').forEach(function (element) < element.addEventListener('click', function(event) < event.preventDefault(); let input = this.parentElement.querySelector('.quantity'); let count = parseInt(input.value) - 1; count = count < 1 ? 1 : count; input.value = count; >); >); // Прибавляем кол-во по клику document.querySelectorAll('.quantity_inner .bt_plus').forEach(function (element) < element.addEventListener('click', function(event) < event.preventDefault(); let input = this.parentElement.querySelector('.quantity'); let count = parseInt(input.value) + 1; count = count >parseInt(input.dataset.maxCount) ? parseInt(input.dataset.maxCount) : count; input.value = parseInt(count); >); >); // Убираем все лишнее и невозможное при изменении поля document.querySelectorAll('.quantity_inner .quantity').forEach(function (element) < element.addEventListener("change", function(event) < event.preventDefault(); if (this.value.match(/[^0-9]/g)) < this.value = this.value.replace(/[^0-9]/g, ''); >if (this.value == "") < this.value = 1; >if (this.value > parseInt(this.dataset.maxCount)) < this.value = parseInt(this.dataset.maxCount); >>); >);
Alexander: 22.02.2023 в 08:15
Спасибо, думаю многим пригодится!
Noname: 20.04.2023 в 14:19
Спасибо друг!
Александр: 24.01.2023 в 21:37
Спасибо большое! Отлично вышло. Немного подшаманил под свой проект css и отправил в форму результат. Как там и было
Alexei: 10.12.2022 в 13:01
Подскажите, а как можно реализовать? допустим мы дошли до цифры 3 и заново начать с цифры 1, грубо говоря зациклить ввод
Владимир: 04.12.2022 в 00:24
Натянул на калькулятор так или иначе ваш же ползунок. https://atuin.ru/blog/oformlenie-polzunka-input-typerange/ Однако как поля для ввода 1.2 и 1.3 здесь сделать так и не понял.
Владимир: 07.11.2022 в 21:05
Спасибо за крутой сайт! А как сделать чтобы 10-е значения можно было дописывать?
Alexander: 08.11.2022 в 16:15
Не совсем понял, сейчас максимум 20, это стоит в атрибуте data-max-count
Владимир: 03.12.2022 в 18:07
Ох я уж и забыл что спрашивал извиняюсь) Опять коснулось, вот такие мы. Допустим для калькулятора площади какой нибудь где вводить нужно 1,5 метра.
EvilDoom: 04.07.2022 в 19:28
А если в инпуте по умолчанию стоит 0. При нажатии на + появляется 1, а после нажимаем на — должен вернуться 0. Что в скрипте нужно поменять?
Alexander: 07.07.2022 в 10:58
count = count < 1 ? 1 : count;