Wykryj, czy wejście zawiera tekst za pomocą CSS - na stronie, którą odwiedzam i której nie kontroluję?


191

Czy istnieje sposób na wykrycie, czy dane wejściowe zawierają tekst za pomocą CSS? Próbowałem użyć :emptypseudoklasy i próbowałem użyć [value=""], ale żadna z nich nie działała. Nie mogę znaleźć żadnego rozwiązania tego problemu.

Wyobrażam sobie, że musi to być możliwe, biorąc pod uwagę, że mamy pseudoklasy dla :checkedi :indeterminate, z których oba są czymś podobnym.

Uwaga: robię to dla stylu „Stylowego” , który nie może wykorzystywać JavaScript.

Zwróć również uwagę, że Stylowy jest używany po stronie klienta na stronach, nad którymi użytkownik nie ma kontroli.


Nie jestem pewien, jak to zrobić za pomocą CSS (który i tak nie aktualizuje się w locie). Jednak z JavaScript jest to łatwe.
ralph.m

Nie sądzę, żebym mógł używać JavaScript. Pracuję nad stylem „stylowym”. Jestem całkiem pewien, że musi to być zrobione całkowicie za pomocą CSS. Jeśli nie aktualizuje się, gdy użytkownik wpisuje tekst, myślę, że jest to wtedy strata czasu. Nie myślałem o tym. Hmm. Przynajmniej nie jest to krytyczne dla stylu, to tylko drobiazg, który miałem nadzieję dodać.
JacobTheDev

Odpowiedzi:


66

Stylowy nie może tego zrobić, ponieważ CSS nie może tego zrobić. CSS nie ma (pseudo) selektorów dla <input>wartości. Widzieć:

:emptySelektor odnosi się tylko do węzłów podrzędnych, a nie do wartości wejściowe.
[value=""] wykonuje pracę; ale tylko dla stanu początkowego . To dlatego, że węzeł jest value atrybutem (który widzi CSS) nie jest taka sama jak węzła value własności (zmieniona przez użytkownika lub DOM javascript, jak i złożone formy danych).

Chyba, że dbają tylko o stanie początkowym, ty musi użyć userscript lub skrypt Greasemonkey. Na szczęście nie jest to trudne. Poniższy skrypt będzie działał w przeglądarce Chrome lub Firefox z zainstalowanym Greasemonkey lub Scriptish lub w dowolnej przeglądarce obsługującej skrypty użytkownika (tj. W większości przeglądarek poza IE).

Zobacz demo ograniczeń CSS oraz rozwiązania javascript na tej stronie jsBin .

// ==UserScript==
// @name     _Dynamically style inputs based on whether they are blank.
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*
// @grant    GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/

var inpsToMonitor = document.querySelectorAll (
    "form[name='JustCSS'] input[name^='inp']"
);
for (var J = inpsToMonitor.length - 1;  J >= 0;  --J) {
    inpsToMonitor[J].addEventListener ("change",    adjustStyling, false);
    inpsToMonitor[J].addEventListener ("keyup",     adjustStyling, false);
    inpsToMonitor[J].addEventListener ("focus",     adjustStyling, false);
    inpsToMonitor[J].addEventListener ("blur",      adjustStyling, false);
    inpsToMonitor[J].addEventListener ("mousedown", adjustStyling, false);

    //-- Initial update. note that IE support is NOT needed.
    var evt = document.createEvent ("HTMLEvents");
    evt.initEvent ("change", false, true);
    inpsToMonitor[J].dispatchEvent (evt);
}

function adjustStyling (zEvent) {
    var inpVal  = zEvent.target.value;
    if (inpVal  &&  inpVal.replace (/^\s+|\s+$/g, "") )
        zEvent.target.style.background = "lime";
    else
        zEvent.target.style.background = "inherit";
}

Przyjrzę się temu skryptowi użytkownika. Dzięki.
JacobTheDev

@MartinGottweis, nie w przypadku OP tak nie jest. To jest [stylowe] pytanie.
Brock Adams

1
@BrockAdams, op mówi, że nie może używać javascript, więc opcja: valid jest dobrym rozwiązaniem. Czy coś mi brakuje?
Martin Gottweis

2
@MartinGottweis, :validopcja wymaga przepisania strony - czego OP nie może zrobić ze stylowym i żadna z pozostałych odpowiedzi w ogóle nie pojawia się w kontekście przeglądania. Użytkownik nie ma kontroli nad odwiedzaną stroną.
Brock Adams

266

Jest to możliwe, z typowymi zastrzeżeniami CSS i możliwością modyfikacji kodu HTML. Jeśli dodasz requiredatrybut do elementu, element będzie pasował :invalidlub w :validzależności od tego, czy wartość kontrolki jest pusta, czy nie. Jeśli element nie ma valueatrybutu (lub ma value=""), wartość kontrolki jest początkowo pusta i staje się niepusty po wprowadzeniu dowolnego znaku (nawet spacji).

Przykład:

<style>
#foo { background: yellow; }
#foo:valid { outline: solid blue 2px; }
#foo:invalid { outline: solid red 2px; }
</style>
<input id=foo required>

Pseudo-klasyfikowane :validi :invalidsą zdefiniowane tylko w dokumentach CSS na poziomie Working Draft, ale obsługa jest dość powszechna w przeglądarkach, z wyjątkiem tego, że w IE jest dostarczana z IE 10.

Jeśli chcesz, aby „puste” zawierały wartości zawierające tylko spacje, możesz dodać atrybut pattern=.*\S.*.

Nie ma (obecnie) selektora CSS do bezpośredniego wykrywania, czy kontrolka wejściowa ma niepustą wartość, więc musimy to zrobić pośrednio, jak opisano powyżej.

Ogólnie rzecz biorąc, selektory CSS odnoszą się do znaczników lub, w niektórych przypadkach, do właściwości elementu ustawionych za pomocą skryptów (JavaScript po stronie klienta), a nie do działań użytkownika. Na przykład :emptydopasowuje element do pustej treści w znaczniku; inputw tym sensie wszystkie elementy są nieuchronnie puste. Selektor [value=""]sprawdza, czy element ma valueatrybut w znaczniku i ma pusty ciąg jako wartość. A :checkedi :indeterminatesą podobne rzeczy. Nie ma na nie wpływu faktyczne działanie użytkownika.


7
Jest to świetne rozwiązanie wtedy i tylko wtedy, gdy każde wejście jest wymagane - jeśli nie, napotkasz sytuację, w której masz puste, ale prawidłowe pole wejściowe, na które nie ma wpływu nieprawidłowy styl . JS jest prawdopodobnie zwycięzcą tego rozwiązania
AdamSchuld

7
to jest brudne, ale cudownie sprytne. Nie jest to rozwiązanie tego pytania, ale z pewnością pomogło
sty

1
Brudne rozwiązanie. Pamiętaj, że może to powodować problemy z autouzupełnianiem w Chrome, jeśli spróbujesz dodać logikę wyświetlania etykiet na podstawie tego LUB, jeśli dane wejściowe nie są w rzeczywistości wymagane, a formularz ma na tej podstawie weryfikację
Artjom Kurapov

1
Semantycznie jest to błędne. Jak wspomniano w poprzednich komentarzach, niektóre dane wejściowe mogą być opcjonalne, a requiredatrybut może uniemożliwić przesłanie formularza.
zhenming

2
Dodano novalidateatrybut na <form>elemencie, aby nie martwić się o czerwony wyświetlacz, gdy pole jest puste po jednokrotnym wypełnieniu:<form ... novalidate> <input ... required /> </form>
Alcalyn

241

Możesz użyć :placeholder-shownpseudoklasy. Z technicznego punktu widzenia symbol zastępczy jest wymagany, ale zamiast tego można użyć spacji.

input:not(:placeholder-shown) {
  border-color: green;
}

input:placeholder-shown {
  border-color: red;
}
<input placeholder="Text is required" />
<input placeholder=" " value="This one is valid" />
<input placeholder=" " />


10
Niestety nie jest to w ogóle obsługiwane przez IE lub Firefox. Źródło: caniuse.com/#feat=css-placeholder-shown
Sean Dawson,

2
Świetna odpowiedź. Obsługa przeglądarki jest do niczego, ale jeśli pojawi się polyfill, :placeholder-shownpowinno to stać się akceptowaną odpowiedzią. requiredMetoda nie uwzględnia przypadków konto pobocznych. Należy zauważyć, że można przekazać spację do symbolu zastępczego i ta metoda będzie nadal działać. Sława.
corysimmons

6
Inną wadą jest to, że wydaje się, że potrzebujesz faktycznie symbolu zastępczego. Innymi słowy, input:not(:placeholder-shown)zawsze będzie pasować, <input/>nawet jeśli nie ma wartości.
redbmk

5
U mnie działa w Chrome, Firefox i Safari. Nie w IE11.
J0ANMM

1
@redbmk, jak wspomniano corysimmons, należy zauważyć, że można przekazać spację do symbolu zastępczego i ta metoda będzie nadal działać.
Naeem Baghi,

32

Zasadniczo wszyscy szukają:

MNIEJ:

input:focus:required{
    &:invalid{ color: red; border-color: red; box-shadow: 0 0 6px red;}
    &:valid,
    &:placeholder-shown{ border-color: green; box-shadow: 0 0 8px green;}
}

Czysty CSS:

input:focus:required:invalid{ color: red; border-color: red; box-shadow: 0 0 6px red;}
input:focus:required:valid,
input:focus:required:placeholder-shown{ border-color: green; box-shadow: 0 0 8px green;}

1
Najwyraźniej właśnie dałeś użycie działającego rozwiązania i masz 0 głosów pozytywnych na WaT?
ProNOOB

5
Świetna odpowiedź. Pseudo-klasa: placeholder-pokazana nie działa w IE ani Edge, więc nie jest to kompletne rozwiązanie. Jest cholernie blisko i sprawia, że ​​chcę zamordować Edge'a za to, że go nie popieram. IE mógłbym zaakceptować, ale Edge? Chodź Microsoft!
Aaron Martin-Colby

2
To nie jest czyste rozwiązanie CSS, jeśli musisz dodać „wymagane” do swojego HTML
user1566694

30
<input onkeyup="this.setAttribute('value', this.value);" />

i

input[value=""]

będzie działać :-)

edytuj: http://jsfiddle.net/XwZR2/


26
Czy to CSS? Wygląda jak HTML i Javascript (ale mogę się mylić).
jww

Brook Adams napisał: [value = ""] działa; ale tylko dla stanu początkowego. Dzieje się tak, ponieważ atrybut value węzła (który widzi CSS) nie jest tym samym, co właściwość value węzła (zmieniony przez użytkownika lub kod javascript DOM i przesłany jako dane formularza). -> Magia polega na aktualizowaniu atrybutu wartości przy zmianach: jsfiddle.net/XwZR2
Tom D.

2
@ JánosWeisz nie, nie będzie. Ten program obsługi zostanie ustawiony, zanim skrypt będzie mógł manipulować tym elementem i będzie mógł współpracować z obsługą dodaną za pomocą addEventListener.
Dinoboff

2
Oczywiście onkeyup zajmuje się tylko wprowadzaniem z klawiatury. Nie zapominaj jednak, że możesz wkleić tekst do pola wprowadzania za pomocą myszy. Wypróbuj: skopiuj tekst do schowka, a następnie kliknij prawym przyciskiem myszy wejście i kliknij Wklej. Zobacz, jak CSS NIE działa. To samo dotyczy przeciągania i upuszczania tekstu do pola wprowadzania za pomocą myszy.
beluga

4
input[value]:not([value=""])- jest lepiej. Dziękuje za wszystko. codepen.io/iegik/pen/ObZpqo
iegik

22

Możesz użyć placeholdersztuczki, jak napisano powyżej bez requiredpola.

Problem requiredpolega na tym, że kiedy coś napisałeś, a następnie skasowałeś - dane wejściowe będą teraz zawsze czerwone jako część specyfikacji HTML5 - wtedy będziesz potrzebować CSS, jak napisano powyżej, aby to naprawić / zastąpić.

Możesz po prostu zrobić coś bez required

<input type="text" placeholder="filter here" id="mytest" />

CSS

#mytest:placeholder-shown {
/* if placeholder is shown - meaning - no value in input */
  border: black 1px solid;
  color: black;
}
#mytest {
  /* placeholder isn't shown - we have a value in input */
  border: red 1px solid;
  color: red;
}

Pióro do kodu: https://codepen.io/arlevi/pen/LBgXjZ


1
To podejście idealnie pasowało do mojego przypadku użycia. Miałem filtry wyszukiwania, które i tak miały symbole zastępcze i chciałem, aby obramowanie pola wprowadzania było podświetlane, gdy była obecna wartość.
Stephen Tuttlebee

10

Możesz skorzystać z symbolu zastępczego i użyć:

input:not(:placeholder-shown) {
  border: 1px solid red;
}

9

Prosty CSS:

input[value]:not([value=""])

Ten kod zastosuje podany CSS podczas ładowania strony, jeśli dane wejściowe są wypełnione.


10
Działa to tylko podczas ładowania strony. Nie dynamiczne wpisywanie wartości.
Ben Racicot

W tej odpowiedzi należy wyraźnie zaznaczyć problem z wczytywaniem strony.
Bryce Snyder

6

Styl można zmieniać w input[type=text]zależności od tego, czy dane wejściowe zawierają tekst, określając styl dla symbolu zastępczego. W tym momencie nie jest to oficjalny standard, ale obsługuje szeroką przeglądarkę, chociaż z różnymi prefiksami:

input[type=text] {
    color: red;
}
input[type=text]:-moz-placeholder {
    color: green;
}
input[type=text]::-moz-placeholder {
    color: green;
}
input[type=text]:-ms-input-placeholder {
    color: green;
}
input[type=text]::-webkit-input-placeholder {
    color: green;
}

Przykład: http://fiddlesalad.com/scss/input-placeholder-css


FYI, to niezawodnie formatuje symbol zastępczy, ale tylko sam symbol zastępczy. Daje to iluzję zmiany koloru tekstu, ale tak już jest, tylko domyślnie z szarym i czarnym.
John Weisz

Cały CSS to tania iluzja, zmieniasz tylko wygląd bez wpływu na rzeczywistą zawartość :-)
vbraun

Właśnie tego potrzebowałem. Wymagałem, aby dane wejściowe zmieniły style, jeśli zawierał tekst, ponieważ projekt elementu zastępczego różni się od stylu wprowadzania. Idealny!
Christopher Marshall,

Działa to w przypadku tła, ale nie obramowań. Nie zagłębiałem się jednak zbytnio w próbę zmiany granicy.
majinnaibu

5

Używanie JS i CSS: nie pseudoklasy

 input {
        font-size: 13px;
        padding: 5px;
        width: 100px;
    }

    input[value=""] {
        border: 2px solid #fa0000;
    }

    input:not([value=""]) {
        border: 2px solid #fafa00;
    }
<input type="text" onkeyup="this.setAttribute('value', this.value);" value="" />

   



1

Prosta sztuczka z jQuery i CSS Jak to:

JQuery:

$('input[value=""]').addClass('empty');
        $('input').keyup(function(){
            if( $(this).val() == ""){
                $(this).addClass("empty");
            }else{
                $(this).removeClass("empty");
            }
        });

CSS:

input.empty:valid{
        box-shadow: none;
        background-image: none;
        border: 1px solid #000;
    }

    input:invalid,
    input:required {
        box-shadow: 3px 1px 5px rgba(200, 0, 0, 0.85);
        border: 1px solid rgb(200,0,0);
    }




    input:valid{
        box-shadow: none;
        border: 1px solid #0f0;
    }

1

zrób to na części HTML w ten sposób:

<input type="text" name="Example" placeholder="Example" required/>

Wymagany parametr będzie wymagał umieszczenia tekstu w polu wejściowym, aby był poprawny.


1
Nie pomaga to wykryć, czy wejście zawiera tekst z CSS, o co pytano.
Jukka K. Korpela

Przepraszam, to faktycznie pomaga ... Umożliwia korzystanie z pseudoklas, jak wyjaśniono w mojej odpowiedzi.
Jukka K. Korpela

1
To jest stylowe pytanie - co oznacza, że ​​OP nie może kontrolować ani zmieniać strony docelowej. Widzi tylko stronę po stronie klienta.
Brock Adams

3
To było bardzo pomocne, oto przykład tego, o czym mówi Xedret
tolmark

****** <wymagane dane wejściowe> && dane wejściowe: ważne {...} ******
FremyCompany

0

Tak! możesz to zrobić za pomocą prostego atrybutu podstawowego z selektorem wartości.

Użyj selektora atrybutu z pustą wartością i zastosuj właściwości input[value='']

input[value=''] {
    background: red;
}


-6

Nie jest to możliwe w przypadku CSS. Aby to zaimplementować, będziesz musiał użyć JavaScript (np $("#input").val() == "".).


2
Wiem, jak to zrobić, muszę to zrobić za pomocą CSS. Przeczytaj komentarze do oryginalnego postu. Zgodnie z moją wiedzą tworzę styl „Stylowy”, który nie może wykorzystywać JavaScript.
JacobTheDev
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.