← Назад к вопросам

Как сверстать стрелку вокруг поля ввода?

2.0 Middle🔥 111 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Верстка стрелки вокруг поля ввода

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

Способ 1: Border с CSS (самый простой)

Самый базовый и эффективный способ - использовать border и border-radius:

export function ArrowInput() {
  const [value, setValue] = useState('');

  return (
    <div className="relative inline-block">
      <input
        type="text"
        value={value}
        onChange={(e) => setValue(e.target.value)}
        placeholder="Enter text..."
        className="px-4 py-2 pr-10 border-2 border-blue-500 rounded-lg outline-none focus:border-blue-700 transition-colors"
      />
      
      {/* Стрелка вправо */}
      <span className="absolute right-3 top-1/2 transform -translate-y-1/2 text-blue-500"></span>
    </div>
  );
}

Способ 2: Стрелка с использованием ::before и ::after

Создаем стрелку чистым CSS без использования иконок:

.input-with-arrow {
  position: relative;
  display: inline-block;
}

.input-with-arrow input {
  padding-right: 40px;
  padding-left: 15px;
  padding-top: 8px;
  padding-bottom: 8px;
  border: 2px solid #3b82f6;
  border-radius: 8px;
  font-size: 16px;
  transition: border-color 0.3s;
}

.input-with-arrow input:focus {
  outline: none;
  border-color: #1e40af;
}

/* Создаем стрелку с ::after */
.input-with-arrow::after {
  content: '';
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 0;
  height: 0;
  border-left: 6px solid #3b82f6;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
}

.input-with-arrow input:focus ~ ::after {
  border-left-color: #1e40af;
}

Способ 3: SVG стрелка (более гибкое решение)

SVG дает больше контроля над внешним видом:

export function InputWithSVGArrow() {
  const [value, setValue] = useState('');

  return (
    <div className="relative inline-block w-full max-w-md">
      <input
        type="text"
        value={value}
        onChange={(e) => setValue(e.target.value)}
        placeholder="Enter text..."
        className="w-full px-4 py-3 pr-12 border-2 border-blue-500 rounded-lg focus:outline-none focus:border-blue-700"
      />
      
      <svg
        className="absolute right-3 top-1/2 transform -translate-y-1/2 w-6 h-6 text-blue-500 pointer-events-none"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
      >
        {/* Простая стрелка вправо */}
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M9 5l7 7-7 7"
        />
      </svg>
    </div>
  );
}

Способ 4: Стрелка по периметру поля (более сложная)

Если нужна стрелка, проходящая вокруг контура поля:

export function InputWithBorderArrow() {
  const [focused, setFocused] = useState(false);

  return (
    <div className={`
      relative w-full max-w-md
      ${focused ? 'border-4' : 'border-2'}
      border-transparent
      transition-all duration-300
      rounded-2xl
      padding-1
      ${focused ? 'border-blue-500' : 'border-gray-300'}
    `}>
      {/* Фон с градиентом для стрелки */}
      <div className="absolute inset-0 rounded-2xl bg-gradient-to-r from-blue-500 via-blue-400 to-blue-500" />
      
      {/* Контент */}
      <div className="relative bg-white rounded-2xl">
        <input
          type="text"
          onFocus={() => setFocused(true)}
          onBlur={() => setFocused(false)}
          placeholder="Hover or focus..."
          className="w-full px-4 py-3 rounded-2xl outline-none"
        />
        
        {/* SVG стрелка в углу */}
        <svg
          className="absolute -top-2 -right-2 w-8 h-8 text-blue-500"
          fill="currentColor"
          viewBox="0 0 24 24"
        >
          <path d="M7 14l5-5 5 5z" />
        </svg>
      </div>
    </div>
  );
}

Способ 5: Анимированная стрелка с rotation

Стрелка, которая вращается при фокусе:

export function AnimatedArrowInput() {
  const [focused, setFocused] = useState(false);

  return (
    <div className="relative inline-block w-full max-w-md">
      <input
        type="text"
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        placeholder="Focus to see animation..."
        className="w-full px-4 py-3 pr-12 border-2 border-blue-500 rounded-lg focus:outline-none focus:border-blue-700"
      />
      
      <svg
        className={`
          absolute right-3 top-1/2 transform -translate-y-1/2
          w-6 h-6 text-blue-500
          transition-transform duration-300
          ${focused ? 'rotate-90' : 'rotate-0'}
        `}
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
      >
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M13 7l5 5m0 0l-5 5m5-5H6"
        />
      </svg>
    </div>
  );
}

Способ 6: Стрелка вокруг поля с border-image

Использование border-image для создания декоративной стрелки:

.input-rounded-arrow {
  position: relative;
  width: 100%;
  max-width: 400px;
  padding: 8px 0;
}

.input-rounded-arrow input {
  width: 100%;
  padding: 12px 16px;
  border: 3px solid transparent;
  border-radius: 12px;
  background-image: linear-gradient(white, white),
    conic-gradient(from 0deg, #3b82f6, #3b82f6);
  background-origin: padding-box, border-box;
  background-clip: padding-box, border-box;
  font-size: 16px;
  transition: background-image 0.3s;
}

.input-rounded-arrow input:focus {
  outline: none;
  background-image: linear-gradient(white, white),
    conic-gradient(
      from 0deg,
      #1e40af,
      #3b82f6,
      #1e40af,
      #1e40af
    );
}

/* Стрелка в правом углу */
.input-rounded-arrow::after {
  content: '';
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 6px;
  height: 6px;
  border-right: 2px solid #3b82f6;
  border-top: 2px solid #3b82f6;
  transform: translateY(-50%) rotate(45deg);
  transition: border-color 0.3s;
}

.input-rounded-arrow input:focus ~ ::after {
  border-color: #1e40af;
}

Способ 7: Полная обертка со стрелками в углах

Создание эффекта, где стрелки находятся в углах поля:

export function InputWithCornerArrows() {
  return (
    <div className="relative w-full max-w-md">
      <div className="relative border-2 border-blue-500 rounded-lg p-0.5">
        {/* Верхняя левая стрелка */}
        <div className="absolute -top-2 -left-2 text-blue-500 text-lg"></div>
        
        {/* Верхняя правая стрелка */}
        <div className="absolute -top-2 -right-2 text-blue-500 text-lg"></div>
        
        {/* Нижняя левая стрелка */}
        <div className="absolute -bottom-2 -left-2 text-blue-500 text-lg"></div>
        
        {/* Нижняя правая стрелка */}
        <div className="absolute -bottom-2 -right-2 text-blue-500 text-lg"></div>

        <input
          type="text"
          placeholder="Input with corner arrows"
          className="w-full px-4 py-3 outline-none bg-transparent"
        />
      </div>
    </div>
  );
}

Способ 8: Стрелка с пульсирующей анимацией

Красивый эффект с пульсированием:

export function PulsingArrowInput() {
  const [focused, setFocused] = useState(false);

  return (
    <style>{`
      @keyframes pulse-arrow {
        0%, 100% {
          opacity: 1;
          transform: translateY(-50%);
        }
        50% {
          opacity: 0.6;
          transform: translateY(-50%) translateX(4px);
        }
      }

      .arrow-pulse {
        animation: pulse-arrow 1s ease-in-out infinite;
      }
    `}</style>

    <div className="relative w-full max-w-md">
      <input
        type="text"
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        placeholder="Focus to see pulsing arrow..."
        className="w-full px-4 py-3 pr-12 border-2 border-blue-500 rounded-lg focus:outline-none focus:border-blue-700"
      />
      
      <svg
        className={`
          absolute right-3 top-1/2 w-6 h-6 text-blue-500 pointer-events-none
          ${focused ? 'arrow-pulse' : ''}
        `}
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
      >
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M13 7l5 5m0 0l-5 5m5-5H6"
        />
      </svg>
    </div>
  );
}

Способ 9: Полный компонент с Tailwind и Heroicons

import { ChevronRightIcon } from '@heroicons/react/24/outline';
import { useState } from 'react';

export function ModernArrowInput({ 
  placeholder = 'Search...',
  onSubmit = () => {}
}) {
  const [value, setValue] = useState('');
  const [focused, setFocused] = useState(false);

  const handleKeyPress = (e) => {
    if (e.key === 'Enter') {
      onSubmit(value);
    }
  };

  return (
    <div className={`
      relative w-full max-w-xl
      transition-all duration-300
      ${focused ? 'ring-2 ring-blue-400' : ''}
    `}>
      <input
        type="text"
        value={value}
        onChange={(e) => setValue(e.target.value)}
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        onKeyPress={handleKeyPress}
        placeholder={placeholder}
        className={`
          w-full px-5 py-3 pr-14
          border-2 rounded-xl
          transition-all duration-300
          ${focused 
            ? 'border-blue-500 shadow-lg' 
            : 'border-gray-300 hover:border-gray-400'
          }
          focus:outline-none
          bg-white
          text-base
        `}
      />
      
      {/* Стрелка с фоном при значении */}
      {value && (
        <button
          onClick={() => onSubmit(value)}
          className={`
            absolute right-2 top-1/2 -translate-y-1/2
            p-2 rounded-lg
            transition-all duration-300
            ${focused 
              ? 'bg-blue-100 text-blue-600 hover:bg-blue-200' 
              : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
            }
          `}
        >
          <ChevronRightIcon className="w-5 h-5" />
        </button>
      )}
    </div>
  );
}

Рекомендации

СпособСложностьПроизводительностьКогда использовать
Text символ (→)Очень низкаяОтличнаяПростые поля, быстрый прототип
CSS ::before/::afterНизкаяОтличнаяСтрелка в углу/краю
SVGСредняяХорошаяКастомные формы, анимации
Border-imageСредняяХорошаяДекоративные границы
Углы стрелокСредняяХорошаяСпециальные дизайны
АнимацияСредняяХорошаяИнтерактивные эффекты
Компонент с иконкойНизкаяОтличнаяProduction код с Tailwind

Итоги

Для быстрого решения используй текстовый символ или SVG иконку справа. Для специальных эффектов - CSS ::after с трансформацией или анимацией. Выбор зависит от дизайн-требований и производительности.

Как сверстать стрелку вокруг поля ввода? | PrepBro