调试 CSS

翻译不完整。 请帮助我们翻译这篇文章!

你有时写 CSS 会碰到这样的问题:结果看起来和你想的不太一样。你可能会认为 selector(选择器)匹配到了元素但是什么都没发生,还可能会觉得盒子的大小与你想的有出入。这篇文章会教你着手调试 CSS,向你展示现代浏览器中的 DevTools 是怎样让你更方便地获悉发生了什么。

必备条件: 会使用计算机、安装基础软件、基本了解文件处理、有 HTML 基础(请参考 HTML 导论)、了解 CSS 工作(请参考 CSS first steps)。
目标: 学习浏览器 DevTools 基础、学会对 CSS 进行简单的审查和编辑。

打开 DevTools

What are browser developer tools 解释了如何在不同的浏览器和平台上打开这些工具。你可能会选择大部分时间在某个浏览器上开发去熟悉里面的工具,不过你还是值得获悉如何在其它浏览器中打开同样的工具。要是你看到多个浏览器间不同的渲染结果,这就会很方便了。

你还会发现,不同的浏览器弹出 DevTools 时会选择把重点放到不同的区域。例如,Firefox 有不错的工具用来可视化处理 CSS 布局,让你能够检查和编辑 Grid LayoutsFlexboxShapes。不过,浏览器都有类似的基础工具用来检查作用于页面元素的 CSS 属性和值,并对它们进行更改。

我们这节课会重点看用于处理 CSS 的 DevTools中的一些有用特性。为此,我会用一个示例。想跟着学习的话,就在新标签页加载该网页吧,并打开 DevTools(上述文章对该工具有描述)。

比较 DOM 和 View Source

刚接触 DevTools 的人可能会在这个方面上有失误:网页源码(或服务器端的 HTML 文件)显示的和 DevTools 的 HTML Pane 显示的相比不太一样。通过 View Source,内容看起来差不多,然而一些差异还是存在的。

浏览器从渲染的 DOM 中已为你纠正了一些错误的 HTML 部分。如果你错误地闭合了元素(比如开始标签是<h2>,结束标签是</h3>。),浏览器会搞清楚你的意图,之后 <h2> 就以 </h2> 结束了。浏览器还会处理好 HTML 文档, JavaScript 做出的更改都会由 DOM 表现出来。

相比之下,View Source 就是服务器端的 HTML 源码。DevTools 内的 HTML tree 展示了浏览器任意时间的渲染结果,让你深入理解正在发生什么。

审查 CSS

从页面上选择一个元素,可以通过以下方法:右键该元素,选择审查元素(Inspect);从 DevTools 左侧 HTML tree 中选择该元素。试试选择 class 为 box1 的元素吧,它是页面上的第一个元素,周围画有边框。

The example page for this tutorial with DevTools open.

If you look at the Rules view to the right of your HTML, you should be able to see the CSS properties and values applied to that element. You will see the rules directly applied to class box1 and also the CSS that is being inherited by the box from its ancestors, in this case to <body>. This is useful if you are seeing some CSS being applied that you didn't expect. Perhaps it is being inherited from a parent element and you need to add a rule to overwrite it in the context of this element.

Also useful is the ability to expand out shorthand properties. In our example the margin shorthand is used.

Click on the little arrow to expand the view, showing the different longhand properties and their values.

You can toggle values in the Rules view on and off, when that panel is active — if you hold your mouse over it checkboxes will appear. Uncheck a rule's checkbox, for example border-radius, and the CSS will stop applying.

You can use this to do an A/B comparison, deciding if something looks better with a rule applied or not, and also to help debug it — for example if a layout is going wrong and you are trying to work out which property is causing the problem.

Editing values

In addition to turning properties on and off, you can edit their values. Perhaps you want to see if another color looks better, or wish to tweak the size of something? DevTools can save you a lot of time editing a stylesheet and reloading the page.

With box1 selected, click on the swatch (the small colored circle) that shows the color applied to the border. A color picker will open up and you can try out some different colors; these will update in real time on the page. In a similar fashion, you could change the width or style of the border.

DevTools Styles Panel with a color picker open.

Adding a new property

You can add properties using the DevTools. Perhaps you have realised that you don't want your box to inherit the <body> element's font size, and want to set its own specific size? You can try this out in DevTools before adding it to your CSS file.

You can click the closing curly brace in the rule to start entering a new declaration into it, at which point you can start typing the new property and DevTools will show you an autocomplete list of matching properties. After selecting font-size, enter the value you want to try. You can also click the + button to add an additional rule with the same selector, and add your new rules there.

The DevTools Panel, adding a new property to the rules, with the autocomplete for font- open

Note: There are other useful features in the Rules view too, for example declarations with invalid values are crossed out. You can find out more at Examine and edit CSS.

Understanding the box model

In previous lessons we have discussed the Box Model, and the fact that we have an alternate box model that changes how the size of elements are calculated based on the size you give them, plus the padding and borders. DevTools can really help you to understand how the size of an element is being calculated.

The Layout view shows you a diagram of the box model on the selected element, along with a description of the properties and values that change how the element is laid out. This includes a description of properties that you may not have explicitly used on the element, but which do have initial values set.

In this panel, one of the detailed properties is the box-sizing property, which controls what box model the element uses.

Compare the two boxes with classes box1 and box2. They both have the same width applied (400px), however box1 is visually wider. You can see in the layout panel that it is using content-box. This is the value that takes the size you give the element and then adds on the padding and border width.

The element with a class of box2 is using border-box, so here the padding and border is subtracted from the size that you have given the element. This means that the space taken up on the page by the box is the exact size that you specified — in our case width: 400px.

The Layout section of the DevTools

Note: Find out more in Examining and Inspecting the Box Model.

Solving specificity issues

Sometimes during development, but in particular when you need to edit the CSS on an existing site, you will find yourself having a hard time getting some CSS to apply. No matter what you do, the element just doesn't seem to take the CSS. What is generally happening here is that a more specific selector is overriding your changes, and here DevTools will really help you out.

In our example file there are two words that have been wrapped in an <em> element. One is displaying as orange and the other hotpink. In the CSS we have applied:

em {
  color: hotpink;
  font-weight: bold;
}

Above that in the stylesheet however is a rule with a .special selector:

.special {
  color: orange;
}

As you will recall from the lesson on cascade and inheritance where we discussed specificity, class selectors are more specific than element selectors, and so this is the value that applies. DevTools can help you find such issues, especially if the information is buried somewhere in a huge stylesheet.

Inspect the <em> with the class of .special and DevTools will show you that orange is the color that applies, and also shows you the color property applied to the em crossed out. You can now see that the class is overriding the element selector.

Selecting an em and looking at DevTools to see what is over-riding the color.

Find out more about the Firefox DevTools

There is a lot of information about the Firefox DevTools here on MDN. Take a look at the main DevTools section, and for more detail on the things we have briefly covered in this lesson see The How To Guides.

在CSS中调试问题

在解决CSS问题时,DevTools可以提供很大的帮助,因此当您发现自己的CSS表现不如预期时,应该如何解决呢? 以下步骤应有所帮助。

从问题中后退一步

任何代码问题都可能令人沮丧,尤其是CSS问题,因为您通常无法获得错误消息用于网络搜索来帮助您找到解决方案。 如果您感到沮丧,请暂时离开该问题一会儿—散步,喝一杯,与同事聊天,或者做一些其他事情。 有时,当您停止思考问题时,解决方案就会神奇地出现,即使没有出现,在感到清爽的时候解决起问题来要容易很多。

你有一个有效的HTML和CSS吗?

浏览器希望您的CSS和HTML能够正确编写,但是浏览器也非常宽容,即使标记或样式表中有错误,浏览器也会尽力显示您的网页。 如果您的代码有错误,浏览器需要猜测您的意思,并且可能会对您的想法做出不同的决定。 此外,两种不同的浏览器可能会以两种不同的方式来解决该问题。 因此,一个好的第一步是通过验证器运行HTML和CSS,以获取并修复任何错误。

属性和值是否被你正在测试的浏览器所支持?

浏览器会忽略他们不理解的CSS。 如果您正在测试的浏览器不支持您正在使用的属性或值,则不会奔溃,但CSS不会被应用。 DevTools通常会以某种方式突出显示不支持的属性和值。 在下面的屏幕截图中,浏览器不支持以下子网格值 grid-template-columns.

Image of browser DevTools with the grid-template-columns: subgrid crossed out as the subgrid value is not supported.

您还可以查看MDN每个属性页底部的浏览器兼容性表。 这些向您显示浏览器对该属性的支持,如果支持该属性的某些用法,而不支持其他用法,则经常会break down。 这里显示了shape-outside属性的兼容性数据。

是否有其它东西覆盖了你的CSS?

在这里,您所学到的关于特定性(specificity)的信息将非常有用。 如果您有一些更特定的内容要覆盖你打算做的,将会比较麻烦。 但是,如上所述,DevTools将向您显示CSS是如何应用的,您可以弄清楚如何使新选择器足够具体,以覆盖旧的CSS样式。

制作一个精简的问题测试用例

如果上述步骤未能解决问题,则您需要做更多调查。 此时最好的做法是创建一个称为简化测试用例的东西。 能够“减化问题”是一项非常有用的技能。 这将帮助您在自己的代码和同事的代码中发现问题,还使您能够报告错误并更有效地寻求帮助。

简化的测试用例是一个代码示例,它以最简单的方式演示了该问题,并删除了无关的周围内容和样式。 这通常意味着将有问题的代码从您的布局中取出,以制作一个仅显示该代码或功能的小示例。

创建一个简化测试用例:

  1. 如果您的标记是动态生成的(例如通过CMS),请生成显示该问题的静态版本。 诸如CodePen之类的代码共享站点可用于托管简化的测试用例,因为它们可以在线访问,并且您可以轻松地与同事共享它们。 您可以先在页面上执行“查看源代码”,然后将HTML复制到CodePen中,然后获取所有相关的CSS和JavaScript并将其包括在内。 之后,您可以检查问题是否仍然明显。
  2. 如果删除JavaScript不能解决问题,请不要包含JavaScript。 如果删除JavaScript确实消除了问题,那么请尽可能多地删除与问题无关的JavaScript,保留导致问题的原因。
  3. 删除所有不会导致此问题的HTML。 删除布局中的组件甚至主要元素。 在保留问题可重现的情况下把代码量尽量减少。
  4. 删除掉任何不影响问题的CSS。

在执行此操作的过程中,您可能会发现导致问题的原因,或者至少能够通过删除特定的东西来打开和关闭它。 当发现一些东西时,应该在代码中添加一些注释。 如果您需要帮助,这些注释将向帮助您的人显示您已经做了哪些尝试。 这很可能会为您提供足够的信息,以便能够搜索可能存在的问题和解决方法。

如果您还没有解决问题,那么减化测试用例可以通过发布到论坛或向同事展示来为寻求帮助提供依据。 如果能够表明在寻求帮助之前您已经完成了简化问题并准确确定问题根源的工作,那么会帮助您更容易地获得帮助。 一个更有经验的开发人员也许能够迅速发现问题并为您指明正确的方向,即使没有,您简化的测试用例也可以使他们快速查看并能够至少提供一些帮助。

如果您的问题实际上是浏览器中的错误,则还可以使用简化的测试用例向相关的浏览器供应商提交错误报告。(e.g. on Mozilla's bugzilla site).

随着对CSS的使用经验越来越丰富,您会发现发现问题的速度越来越快。 但是,即使我们中最有经验的人有时也会发现自己想知道到底发生了什么。 采取有条不紊的方法,简化测试用例,并向他人解释问题,通常会找到解决方法。

In this module

  1. Cascade and inheritance
  2. CSS selectors
  3. The box model
  4. Backgrounds and borders
  5. Handling different text directions
  6. Overflowing content
  7. Values and units
  8. Sizing items in CSS
  9. Images, media, and form elements
  10. Styling tables
  11. Debugging CSS
  12. Organizing your CSS