Стилизация file input

Тренажер по CSS для пользователей с начальным уровнем подготовки.

Тренажер CSS

В этой серии заданий вы попрактикуетесь в стилизации стандартного элемента HTML для загрузки файлов `<input type=\"file\">`. Поскольку прямое изменение внешнего вида этого элемента ограничено, мы будем использовать распространенные техники, такие как скрытие оригинального инпута и стилизация связанного с ним элемента `<label>`, а также использование псевдоэлемента `::file-selector-button` для более прямого контроля над кнопкой выбора файла. Задания построены от простого к сложному, начиная с базового скрытия и стилизации метки, и заканчивая добавлением иконок и состояний.

Список тем

Скрытие стандартного input type="file"

Стандартный `<input type="file">` сложно стилизовать напрямую. Первым шагом в создании кастомного элемента загрузки является скрытие оригинального инпута. Скройте элемент с id `file-upload`, используя подходящее CSS свойство. При этом элемент должен оставаться доступным для взаимодействия (например, через связанный `<label>`).

CSS
.file-input-wrapper input[type="file"] {
  input1: 0;
  input2: 0;
  input3: absolute;
  input4: -9999px;
  input5: -9999px;
}
HTML
<div class="file-input-wrapper">
  <label for="file-upload" class="file-upload-label">
    Выберите файл
  </label>
  <input type="file" id="file-upload" name="file-upload">
</div>
Чтобы скрыть элемент, сохранив его функциональность (например, возможность получить фокус или быть активированным через label), можно использовать несколько техник. Одна из них — установить ему абсолютное позиционирование, нулевые размеры, нулевую непрозрачность и скрыть переполнение. Другой, более простой способ для этого случая - использовать свойство, которое визуально скрывает элемент, но оставляет его в потоке документа для доступности. Подумайте о свойстве `opacity` или комбинации свойств для позиционирования вне экрана.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Базовая стилизация Label как кнопки

Теперь, когда оригинальный input скрыт, стилизуйте элемент `<label>`, чтобы он выглядел как кнопка. Задайте ему фоновый цвет `#4CAF50`, внутренние отступы 10px сверху/снизу и 20px слева/справа, белый цвет текста и сделайте так, чтобы курсор менялся на указатель при наведении.

CSS
.file-input-wrapper input[type="file"] {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
  left: -9999px;
  top: -9999px;
}

.file-upload-label {
  input1: #4CAF50;
  input2: #ffffff;
  padding: 10px 20px;
  input3: pointer;
  input4: inline-block; /* Добавлено для корректного применения padding */
  border-radius: 4px;
}
HTML
<div class="file-input-wrapper">
  <label for="file-upload" class="file-upload-label">
    Выберите файл
  </label>
  <input type="file" id="file-upload" name="file-upload">
</div>
Используйте свойства `background-color` для фона, `padding` для внутренних отступов, `color` для цвета текста и `cursor` для изменения вида курсора. Чтобы стили применились корректно, может потребоваться изменить тип отображения элемента `label`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Добавление состояний Hover и Active для Label

Сделайте кастомную кнопку более интерактивной. Добавьте стили для состояний `:hover` и `:active`. При наведении (`:hover`) измените фоновый цвет на `#45a049`. При нажатии (`:active`) измените фоновый цвет на `#3e8e41` и добавьте небольшое смещение вниз на 2px.

CSS
.file-input-wrapper input[type="file"] {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
  left: -9999px;
  top: -9999px;
}

.file-upload-label {
  background-color: #4CAF50;
  color: #ffffff;
  padding: 10px 20px;
  cursor: pointer;
  display: inline-block;
  border-radius: 4px;
  input1: relative; /* Необходимо для смещения */
  transition: background-color 0.2s ease, top 0.1s ease;
}

.file-upload-label:input2 {
  background-color: #45a049;
}

.file-upload-label:input3 {
  background-color: #3e8e41;
  input4: 2px;
}
HTML
<div class="file-input-wrapper">
  <label for="file-upload" class="file-upload-label">
    Выберите файл
  </label>
  <input type="file" id="file-upload" name="file-upload">
</div>
Используйте псевдоклассы `:hover` и `:active` для элемента `.file-upload-label`. Для смещения при нажатии используйте `position: relative` и свойство `top`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Стилизация кнопки через ::file-selector-button

Современные браузеры поддерживают псевдоэлемент `::file-selector-button`, который позволяет стилизовать непосредственно кнопку внутри `<input type="file">`. В этом задании не нужно скрывать инпут. Вместо этого примените стили к `::file-selector-button`: фоновый цвет `#007bff`, белый цвет текста, уберите стандартную рамку и добавьте свою рамку толщиной 1px сплошную (`solid`) цветом `#007bff`, а также внутренние отступы 8px и скругление углов 4px.

CSS
input[type="file"] {
  margin-top: 10px; /* Небольшой отступ для наглядности */
}

input[type="file"]input1 {
  input2: #007bff;
  input3: #ffffff;
  padding: 8px;
  input4: 1px solid #007bff;
  input5: 4px;
  cursor: pointer;
  transition: background-color 0.2s ease;
}

input[type="file"]::file-selector-button:hover {
  background-color: #0056b3;
  border-color: #0056b3;
}
HTML
<div>
  <label for="file-upload-direct">Стандартный инпут:</label>
  <input type="file" id="file-upload-direct" name="file-upload-direct">
</div>
Используйте селектор `input[type="file"]::file-selector-button`. Примените свойства `background-color`, `color`, `border`, `padding` и `border-radius`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Добавление иконки к Label

Улучшите внешний вид кастомной кнопки (стилизованного `<label>`), добавив иконку слева от текста. Используйте псевдоэлемент `::before` для `.file-upload-label`. Задайте ему фоновое изображение `https://naytikurs.ru/img/7.png`, установите размеры 16px на 16px, сделайте его блочно-строчным (`inline-block`) и добавьте правый отступ 8px, чтобы отодвинуть текст.

CSS
.file-input-wrapper input[type="file"] {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
  left: -9999px;
  top: -9999px;
}

.file-upload-label {
  background-color: #4CAF50;
  color: #ffffff;
  padding: 10px 15px;
  cursor: pointer;
  display: inline-block;
  border-radius: 4px;
  position: relative;
}

.file-upload-label:hover {
  background-color: #45a049;
}

.file-upload-labelinput1 {
  input2: "";
  input3: url('https://naytikurs.ru/img/7.png');
  background-size: contain; /* Масштабируем изображение */
  background-repeat: no-repeat;
  width: 16px;
  height: 16px;
  input4: inline-block;
  margin-right: 8px;
  input5: middle; /* Выравниваем иконку по центру текста */
}
HTML
<div class="file-input-wrapper">
  <label for="file-upload" class="file-upload-label">
    Загрузить файл
  </label>
  <input type="file" id="file-upload" name="file-upload">
</div>
Создайте правило для `.file-upload-label::before`. Используйте свойство `content` (с пустым значением `""`), `background-image`, `width`, `height`, `display` и `margin-right`. Для корректного вертикального выравнивания иконки относительно текста может понадобиться свойство `vertical-align`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Стилизация при фокусе через :focus-within

Важно обеспечивать визуальную обратную связь при навигации с клавиатуры. Используйте псевдокласс `:focus-within` на родительском контейнере `.file-input-wrapper`, чтобы применить стиль к `.file-upload-label`, когда скрытый `<input>` получает фокус. Добавьте внешнюю обводку (`outline`) толщиной 2px, пунктирную (`dashed`), синего цвета (`blue`) к `.file-upload-label`, когда `.file-input-wrapper` содержит элемент в фокусе.

CSS
.file-input-wrapper input[type="file"] {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
  left: -9999px;
  top: -9999px;
}

.file-upload-label {
  background-color: #4CAF50;
  color: #ffffff;
  padding: 10px 20px;
  cursor: pointer;
  display: inline-block;
  border-radius: 4px;
  transition: background-color 0.2s ease;
}

.file-upload-label:hover {
  background-color: #45a049;
}

.file-input-wrapperinput1 .file-upload-label {
  input2: 2px dashed blue;
}
HTML
<div class="file-input-wrapper">
  <label for="file-upload" class="file-upload-label">
    Выберите файл
  </label>
  <input type="file" id="file-upload" name="file-upload">
</div>
<p style="margin-top: 10px; font-size: 12px;">Кликните вне кнопки, затем нажмите Tab, чтобы увидеть эффект фокуса.</p>
Используйте селектор `.file-input-wrapper:focus-within .file-upload-label`. Примените свойство `outline` со значениями толщины, стиля и цвета.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Отображение имени файла (стилизация)

Часто после выбора файла требуется показать его имя. Хотя само имя файла устанавливается через JavaScript, мы можем подготовить и стилизовать область для его отображения. Добавьте элемент `<span>` с классом `file-name` после `<label>`. Стилизуйте этот span: добавьте левый отступ 10px, установите серый цвет текста `#555` и курсивный стиль шрифта.

CSS
.file-input-wrapper input[type="file"] {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
  left: -9999px;
  top: -9999px;
}

.file-upload-label {
  background-color: #4CAF50;
  color: #ffffff;
  padding: 10px 20px;
  cursor: pointer;
  display: inline-block;
  border-radius: 4px;
}

.file-name {
  input1: 10px;
  input2: #555555;
  input3: italic;
}
HTML
<div class="file-input-wrapper">
  <label for="file-upload" class="file-upload-label">
    Выберите файл
  </label>
  <input type="file" id="file-upload" name="file-upload">
  <span class="file-name">Файл не выбран</span>
</div>

<!-- 
Примечание: Динамическое обновление текста 'Файл не выбран' на имя 
реального файла требует JavaScript, что выходит за рамки этого CSS-упражнения.
-->
Добавьте `<span class="file-name">Файл не выбран</span>` в HTML. В CSS создайте правило для `.file-name`. Используйте свойства `margin-left`, `color` и `font-style`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку
НайтиКурс.Ру