Почему css срабатывает только при required в форме?
Потому что оно так работает.
Следите JS'ом событие input и проверяйте, заполнено ли поле...Если заполнено, добавляете класс со стилями аналогичными focus и active

snippet
Потому что состояние валидности(valid) происходит только при required для текстовых полей. Спецификация.
Для полей tel, number, и других специфичных происходит проверка типа, потому там сработает. В тексте какая вам проверка-то, потому флаг required заставляет проверить 1+ символов на наличие, потому и работает. Сам на днях мучался... Мб попробовать pattern применить с регуляркой на любой символ
в принципе, если развернуть стили, к не required применить паттерн типа такого:`pattern="[*]{1,}"` и применить к `input[type="text']:not([required])` то тоже будет работать.