Ferpalaciosd
Ferpalaciosd

Reputation: 107

Font Family Declaration Doesn't Work

Going through a CSS course, I've bumped with an interesting problem.

Defining my font-family on body doesn't make any changes on the displayed fonts, but it works when defined with * or everywhere else, (like p, headlines, and so on). Why could this be?

Here you have the code:

This is the index.html

<!DOCTYPE HTML>
<html lang="en">
    <head>
       <meta charset="utf-8">
        <title>Welcome</title>
        <link rel="stylesheet" href="css/reset.css" type="text/css">
        <link rel="stylesheet" href="css/style.css" type="text/css">
        <link href="http://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body> ...
    </body>
</html>

This is the style.css

body{
    font-family: 'Lato', sans-serif;
    font-size: 15px;
    line-height: 1.5em;
}

I'm also using Meyer's reset.css

Thank you!

Upvotes: 1

Views: 7114

Answers (2)

Woodrow Barlow
Woodrow Barlow

Reputation: 9047

tl;dr: always load resets and external resources before loading your site's custom CSS resources.


Explanation

What you've got here is a specificity issue with your reset CSS code.

When two CSS rules conflict with each other, the browser will use the one with the most specific selector of the two (or, in the case of equal specificity, it uses the last rule loaded).

The Mozilla Developer's Network defines "Specificity" as:

The specificity is a weight that is applied to a given CSS declaration based on the count of each selector type. In the case of specificity equality, the latest declaration found in the CSS is applied to the element. Specificity only applies when the same element is targeted. CSS rules that directly target an element will always take precedence over rules that an element inherits from an ancestor.

You said you're using Meyer's CSS Reset. That file contains a line that says font: inherit, which directly conflicts with your font-family rule (as well as your font-size). In this case, you've fallen prey to the last sentence in that definition of specificity: the reset's font property is being applied to paragraphs, headings, lists, etc., and "rules that directly target an element will always take precedence over rules that an element inherits from an ancestor" (in this case, the ancestor being the body.

You've got a couple of options here. First of all, double check that you're loading your CSS after the reset. That might fix it, but it might not. You can make your selector more specific than the selectors in the reset, which shouldn't be hard since they are designed to use the lowest specificity possible. This is why using body * as a selector worked.

The third option is one that is not recommended: using an !important decorator on any rules that you want to be treated as higher-priority than all other rules. This is dangerous, because it can easily cause unanticipated collisions.


Examples

Non-Working Example: Here is an example that doesn't work. This example doesn't work because Stack Snippets loads the CSS section before the HTML section -- since I'm including the reset in the HTML section, and since both CSS resources have a conflicting same-specifity rule, the most recently-loaded rule gets applied.

body {
  font-family: 'Lato', sans-serif;
}
<link rel="stylesheet" href="http://meyerweb.com/eric/tools/css/reset/reset.css" type="text/css">
<link href="http://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css">

<p>Hello, world</p>

Working Example: Re-Order CSS Resources: Here you can see that if I explicitly load my CSS after the reset, the problem is resolved. Now my reset's rule is being used.

<link rel="stylesheet" href="http://meyerweb.com/eric/tools/css/reset/reset.css" type="text/css">
<link href="http://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css">

<style type="text/css">
  body {
    font-family: 'Lato', sans-serif;
  }
</style>

<p>Hello, world</p>

Working Example: Use a More Specific Selector: This one works if you can't change the order in which your resources are included.

body * {
  font-family: 'Lato', sans-serif;
}
<link rel="stylesheet" href="http://meyerweb.com/eric/tools/css/reset/reset.css" type="text/css">
<link href="http://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css">

<p>Hello, world</p>

Working Example: Use the !important Decorator: Like I said before, always think long and hard about using an !important decorator, as they're generally considered bad practice.

body {
  font-family: 'Lato', sans-serif !important;
}
<link rel="stylesheet" href="http://meyerweb.com/eric/tools/css/reset/reset.css" type="text/css">
<link href="http://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css">

<p>Hello, world</p>

Upvotes: 3

code and pixels
code and pixels

Reputation: 674

Maybe swap the order of the web font (google) and style CSS files. I can't replicate your issue (tried in JSFiddle & Codepen), but maybe you're seeing a dependency issue (referencing the font name before it is being made available).

Another, arguably better, option would be to not call the google font CSS file at all, and instead add an import statement to the top of your style.css file, like so:

@import url(http://fonts.googleapis.com/css?family=Lato);

Hope that helps.

Upvotes: 0

Related Questions