It is enough to check the first 5 items of the list before you deliver a markup to the client. For production, check the first 6 of them.
  1. Markup matches the design
  2. Cross-browser identity, encoding, and DOCTYPE
  3. Validity (including CSSLint and JSHint), accessibility (ARIA, WCAG), microformats 1 & 2, and microdata
  4. Independent CSS blocks: cascade minimization, BEM usage
  5. The site should look good in all the standard resolutions (1024 px and more). There should be no horizontal scroll. The site should fit the screen on mobile devices
  6. Correct look after usage of the real text input. Reliability of the markup
  7. CSS should be written using preprocessors (LESS/Sass/Stylus). Preferable usage of build systems (Grunt/Gulp) and postprocessors (PostCSS/Autoprefixer)
  8. Check and optimization of a page loading speed (GTmetrix/Google PageSpeed Insights)
  9. Retina support
  10. Win/Mac/Linux font analogs presence
  11. Accessibility when images are slowly loading or switched off.
  12. HTML5 forms, linking, validation
  13. Proper semantics. Clean HTML and CSS code, consistency, neatness
  14. Correct structure of headers (H1, H2, etc. and TITLE)
  15. Operability without (or with not yet loaded) JavaScript
  16. Operability without Flash
  17. Enlarged text causes no bugs
  18. Important little things

Point 13. Proper Semantics: Good and Bad Practices

Keep in mind, that semantics can be used in both elements and class names. And BEM class hierarchy is the new level of semantics.


  • Float: left for all the blocks is the worst thing ever. Fortunately, nowadays it’s less common. If a crazy coder emulates table cells placing blocks one after another like bricks, get him out! It can be checked by Web Developer Outline → Float elements. If red blocks are everywhere, you can throw the code away.
  • Block indentation should be created by block margin, but not by a margin of the content sticking outside.
  • The absence of titles is bad.
  • The absence of img alt= .. is bad.
  • Hacks for browsers inside main.css are bad (either with or without filters). “Without filters” is if we just type {zoom: 1;}. It is extremely bad because it affects all the IEs, not just the target ones. “With filters” is if we use (* html, *+html, and so on). It is bad again because it spoils the code and makes it less readable. Some hacks can even be invalid and can break CSSLint run. Conditional Comments used to be considered a good practice, but they are bad too. They increase the amount of CSS files and spread the code to different places. Nowadays, it is recommended to use special classes like html.ie7, html.ie8, and so on (from HTML5 Boilerplate). It’s also a good practice to use Modernizr feature detection (classes like…) and JS detection of browser and platform (e.g. CSS Browser Selector generating classes like…).
  • Not checking forms tabindex is bad.
  • Writing styles without attention to element placement logic is bad. For instance, if the element is always on the top, it must have a high z-index. If it looks good right now, you can’t be sure it will last forever. Styles have to be rock-solid. If an element has to be on the same place no matter of a surrounding, use position:absolute, but never float. Independent blocks shouldn’t be in the same block together (e.g. company phone number and site search). Placement of independent blocks should be absolute, not float.
  • Presentational classes (e.g. .right, .red) are very bad.
  • For a presentational purpose use pseudo-elements instead of empty blocks.
  • It is bad for standard elements to have no basic styles. In other words, just h1, h2, ul, table, etc. have to look nice without classes. In other words – just use Normalize and not Reset CSS.
  • Lack of gradual elaboration of text styles is bad. Suppose a style is specified for each element separately but the outer-block element looks totally different. For example, a text without paragraphs can be of an absolutely different style from the rest of the elements in the block. It is good to gradually specify styles upwards from below. It is important not to mix text styles and block styles now. Cascade styling for text is good, but for blocks, it’s better to use BEM.
  • Over detailed global styles are even worse. For example:
    a {font: italic 10px Tahoma;} /* Hate! Hate! Hate!!11 */
    You will have to redefine the link style for every block afterwards.
  • Element’s size and positioning should be specified in the same measurement units. Block width/height set in px and margin/padding in em is weird and most likely is a mistake. It is better to set line-height by a coefficient (1, 1.2, 1.4, …). It is an extent to which font-size will be multiplied, and you’ll get line spacing without setting units of measurement. If you have font-size/height in em, then set margin/padding in em, too. It is a classic example of a list dl-dt-dd: dt and dd are placed in front of each other by dragging dd upwards with the negative margin value. Or you can use padding to create a space for some text block with position: absolute. Padding and height of text elements (paragraphs, table cells) should be in em so that font size will be increased correctly.
  • It is bad (unacceptable!) to put styles on selectors of nested standard tags without classes. Suppose, we have something like
    h2 a span { some tough thing like a picture with graphics, which overlays our header’s text}
    And when the user suddenly types the same expression in WYSIWYG form, we get an awesome bug. On the contrary, you can use block .b-text (see BEM) for single text tags displaying from a database.
  • It is bad to define visual appearance of elements directly through js: $(‘.element’).css(color,”#f00″). It should be done by classes setting/changing.


  • BEM! Important note, it is a methodology, not a tool. It is enough to create ordinary web sites using only BEM CSS without block library and bem-tools. Avoiding cascade is necessary, and BEM is one of the best solutions for that.
  • Structuring code blocks reflecting document logic is good. You should create div where it’s logically appropriate but presentationally useless. Vice versa try not to put extra div where it is not structure caused and used only for visual effects.
  • HTML5 Boilerplate is a great basic template from the gurus. You can start using it and join its development. Send your contributions there!
  • Use existing development solutions, third-party modules, jQuery plugins. Don’t reinvent the wheel. If you decide to reinvent it anyway, then support it, keep your code library up to date (add the new code and update the old one after each project).
  • Text styles have to be atomic for text blocks, which are edited through an admin panel. Let’s say we have a text block with the structure like this:
    .content-text h1
    .content-text .entry
    .content-text .entry .somenamedblock

    In this case .somenamedblock has to get text style directly: .somenamedblock {font: …; color: …;}. Otherwise, we’ll be unable to style it in the WYSIWYG editor.
  • Same html code should be used for blocks with identical content on the front and inner pages. It can be achieved using block and element modifiers, but not through modIfying the parent (e.g. cascade from body.pagename).

Point 18. Important Little Things

  • Logo on the inner pages should be linked to the main page. On the title page logo should be h1. On the insides h1 should be a content header, and Logo should be div.
  • Each page should have unique TITLE of the format
    About Us — %CompanyName%.
  • All the pages should be interlinked and checked for dead links.
  • All the links should react on :hover, :active, and :focus. It can be done by showing/removing underline, changing color – anything. All the links should react on :visited, except menu items.
  • Check all the interactive elements that should work are working.
  • Content should go at the beginning of the page before any sidebars or other stuff.
  • All the created pages should be sliced into templates beforehand so that they can be easily integrated by programmers.
  • Content has to have a proper copyright.
  • There should be both apple-touch-icon and favicon.ico (better include 32×32, 48×48, and 64×64 versions inside).
  • There should be no unnecessary comments, unused redundant files, old versions, etc. All the backups can be found in version control system if needed (e.g. Git or SVN). Trash in the living project complicates its development.
  • Sizes of blocks depending on the text content should be specified in em, not px.
  • In case if link’s URL is unknown, it should be equal to its anchor spelled in latin characters. Spaces and special characters should be replaced with dashes.
  • Skype plugin shouldn’t break the markup.
  • Textarea resizing shouldn’t break it as well.
  • When checking overall frontend, make sure the response header for a 404 page is 404 and not 200.
  • It’s a good practice to specify sizes of programmatically generated images in CSS.
  • Check spelling at least in Word, preferably – using special web-typography services.
  • Links to external resources should be with target=”_blank”. It’s better to mark them with an icon “external link”.
  • Of course, images should be placed in a separate folder, css in another one, and js in its own folder, too. Graphics that are not a part of the design (e.g. illustrations, photos in a news, etc.) should be placed in an individual folder e.g. “Userfiles”.
  • Images should be scalable depending on the window size (max-width:100%; height:auto;).
Original article by Ihor Zenich, Frontend Developer at EPAM Systems.