Потому что opacity регулирует прозрачность всего блока.
Если фон одноцветный, задаешь так:
background-color: rgba(0,0,0, 0.5)
Это будет черный полупрозрачный цвет.
Если у тебя картинка, то без хаков не обойдется скорее всего. Попробуй использовать псевдоэлемент, задавать фон для него, а его прозрачность никак не будет влиять на сам блок. Псевдоэлемент засовываешь под контент
Как сделать так, чтоб буквы оставались видимыми а фон становился прозрачным?