문제

I'm trying to apply a custom font in my CSS for all non-input fields under the body (I'm using SASS btw). How do I do that? This isn't working:

body {
    &:not(input,select,textarea) { 
        font-family:'Roboto', sans-serif; 
    }
}

Edit

I originally posted this question because I suspected (incorrectly) that input fields inherited the font styles from the body. This isn't the case in general. However, I was using the Twitter Bootstrap framework, and it turns out that they've set font-family:inherit; on the input fields (which forces them to inherit the font set on the body elements).

도움이 되었습니까?

해결책

I should probably preface this answer with a note that it's usually not necessary — and not a good idea — to apply a font-family style to every descendant of body, because font properties are inherited by default by most elements anyway (except form elements and tables if I'm not wrong).

By forcibly applying font-family to every descendant of body, that is, body *, you're effectively blocking inheritance for all descendants, even if you try to set a different font family on one of them expecting its own descendants to inherit.

It should be sufficient to apply the font-family style to body and allow its descendants to inherit it organically (and possibly do the same with table elements in a separate selector or ruleset). As I've mentioned, the form elements you're trying to exclude, i.e. input,select,textarea, do not inherit fonts by default in most browsers anyway.

That being said, the reason why your SCSS doesn't work is because :not() doesn't accept a list of selectors in CSS. That's a feature of jQuery. Quoting my own answer to this question:

First and foremost, to answer the question directly: you can't pass a comma-separated selector list. For example, while the given selector works in jQuery as demonstrated in the fiddle, it isn't valid CSS3:

/* If it's not in the Α, Β or Γ sectors, it's unassigned */
#sectors > div:not(.alpha, .beta, .gamma)

Is there a workaround for this if I really want to avoid relying on a script?

Thankfully, in this case, there is. You simply have to chain multiple :not() selectors, one after another, in order to make it valid CSS3:

#sectors > div:not(.alpha):not(.beta):not(.gamma)

Therefore the solution to your problem is to chain multiple :not() selectors:

body {
    :not(input):not(select):not(textarea) { 
        font-family:'Roboto', sans-serif; 
    }
}

Notice that I do not use the & combinator here. This SCSS will compile to the following CSS, with the space following body being a descendant combinator and the :not()s representing any element other than the ones being excluded:

body :not(input):not(select):not(textarea) { 
    font-family: 'Roboto', sans-serif; 
}

Using & will cause the :not() selectors to be attached directly onto body:

body:not(input):not(select):not(textarea) { 
    font-family: 'Roboto', sans-serif; 
}

Which means you'd be matching body, and not any of its descendants. It's also a uselessly verbose selector because the body element can never be either an input, select, or textarea. But, again, you might as well just go ahead with applying this declaration to body. You should avoid applying inherited declarations to all elements unless absolutely necessary.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top