What the heck, HTML and CSS?

Reasons your your HTML and/or CSS is broken. A curated list of commonly frustrating HTML and CSS quandaries, miscues, and dilemmas.

Created by @mdo.

Forked by @paulmolluzzo.

Contents

Declare a doctype

Always include a doctype. I recommend the simple HTML5 doctype:

<!DOCTYPE html>

Skipping the doctype can cause issues with malformed tables, inputs, and more.

Box model math

Elements that have a set width become wider when they have padding and/or border-width. To avoid these problems, make use of the now common box-sizing: border-box; reset.

Rem units and Mobile Safari

While Mobile Safari supports the use of rems in all property values, it seems to break when rems are used in dimensional media queries and infinitely flashes the page's text in different sizes.

For now, use ems in place of rems.

html {
  font-size: 16px;
}

/* Doesn't work */
@media (min-width: 40rem) {
  html {
    font-size: 20px;
  }
}

/* Works properly */
@media (min-width: 40em) {
  html {
    font-size: 20px;
  }
}

Help! If you have a link to an Apple or WebKit bug report for this, I'd love to include it. I'm unsure where to report this as it only applies to Mobile, and not Desktop, Safari.

Floats first

Floated elements should always come first in the document order. Floated require something to wrap around, otherwise they can cause a step down effect, instead appearing below the content.

<div class="parent">
  <div class="float">Float</div>
  <div class="content">
    <!-- ... -->
  </div>
</div>

Floats and clearing

If you float it, you probably need to clear it. Any content that follows an element with a float will wrap around that element until cleared. To clear floats, use one of the following techniques.

Use the micro clearfix to clear your floats with a separate class.

.clearfix:before,
.clearfix:after {
  content: " ";
  display: table;
}
.clearfix:after {
  clear: both;
}

Alternatively, specify overflow, with auto or hidden, on the parent.

.parent {
  overflow: auto; /* clearfix */
}
.other-parent {
  overflow: hidden; /* clearfix */
}

Be aware that overflow can cause other unintended side effects, typically around positioned elements within the parent.

Pro-Tip! Keep your future self and your coworkers happy by including a comment like /* clearfix */ when clearing floats as the property can be used for other reasons.

Floats and computed height

A parent element that has only floated content will have a computed height: 0;. Add a clearfix to the parent to force browsers to compute a height.

Floated elements are block level

Elements with a float will automatically become display: block;. Do not set both.

.element {
  float: left;
  display: block; /* Not necessary */
}

Fun fact: Years ago, we had to set display: inline; for floats to work properly in IE6. However, those days have long passed.

Vertical margins collapse

Top and bottom margins can and will collapse in many situations, but never for floated or absolutely positioned elements. Read this MDN article to find out more.

Horizontal margins will never collapse.

Styling table rows

Table rows, <tr>s, cannot be styled unless you set border-collapse: separate; on the parent <table>.

Firefox and <input> buttons

For reasons unknown, Firefox still applies styles to submit and button <input>s that cannot be overridden via custom CSS. Stick to <button> elements.

<!-- Not so good -->
<input type="submit" value="Save changes">
<input type="button" value="Cancel">

<!-- Super good everywhere -->
<button type="submit">Save changes</button>
<button type="button">Cancel</button>

Some of Firefox's styles can be overridden with this snippet of CSS:

input::-moz-focus-inner {
  border: 0;
  padding: 0;
}

However, as David Walsh outlines, this doesn't fix everything. Just use the <button> element.

Always set a type on <button>s

The default value is submit, meaning any button in a form can submit the form. Use type="button" for anything that doesn't submit the form and type="submit" for those that do.

<button type="submit">Save changes</button>
<button type="button">Cancel</button>

For actions that require a <button> and are not in a form, use the type="button".

<button class="dismiss" type="button">x</button>

Internet Explorer's selector limit

Internet Explorer 9 and below have a max of 4,096 selectors per stylesheet. Anything after this limit is ignored by the browser. Either split your CSS up, or start refactoring. I'd suggest the latter.

Position explained

Elements with position: fixed; are placed relative to the browser viewport. Elements with position: absolute; are placed relative to their closest parent with a position other than static (e.g., relative, absolute, or fixed).

Position and width

Don't set width: 100%; on an element that has position: [absolute|fixed];, left, and right. The use of width: 100%; is the same as the combined use of left: 0; and right: 0;. Use one or the other, but not both.

Fixed position and transforms

Browsers break position: fixed; when an element's parent has a transform set. Using transforms creates a new containing block, effectivly forcing the parent to have position: relative; and the fixed element to behave as position: absolute;.

See the demo and read Eric Meyer's post on the matter.