For all of Cantilever’s history, we have maintained a clear and specific style for all of our website builds (BEM syntax, vanilla JS, ITCSS, things like that). We would train new people in this style as they worked on our stuff. Over time, we have found that while effective, this style is just very difficult to communicate. In fact, any web development style is hard to communicate, particularly in a remote team.
As of Fall 2020, we have decided that instead of enforcing a strict stylistic approach to every website build, we instead maintain general quality standards. In other words, we measure output, not input. This will allow different talented developers to come in and be effective sooner. It will also allow the whole team to witness different approaches we might not have otherwise permitted to be tried.
The downside, of course, is that we have to very picky about the work we consider "good enough." Our standards are as high as ever when it comes to user experience and Digital Hospitality. We must always provide unparalleled quality and value to users.
This change is in recognition that the web itself has changed. More valid approaches are possible in 2020 than in 2011 when we started. So long as developers adhere to our overall principles and deliver an outstanding user experience, we can be satisfied that the work is Cantilever-y.
To inform design and development and ensure that QA is done in regard to a common core Cantilever standard of quality, we will maintain this document to outline what we and our clients expect of a Cantilever product.
Different projects will have different requirements in various areas. An internal app, for instance, must be incredibly fast, but doesn’t require any SEO attention. A blog, meanwhile, doesn’t need much visual polish, but SEO is imperative. The documentation for each project should outline our and the client’s expectations within each category.
All markup should be clean, semantic, and readable All media should include text fallbacks Interactive component states should be maintained using ARIA tags, not classes Avoid accessibility antipatterns like turning off focus states, disallowing text selection, JS-only rendering, etc. Ensure that design work is accessible (high contrast, sufficient text size)
Meet or exceed the requirements of our Accessibility checklist: https://www.notion.so/cantilever/Perform-an-Accessibility-Audit-e1241a8e9d164a1fa09972e0e06f3ce4
Meets or exceeds checklist criteria, including select AAA standards.
Ensure all user-facing pages load in under 3 seconds on prod, except for extreme circumstances.
Ensure that user-facing pages load in under 2 seconds on prod, except for special cases Avoid serving resources on a page that are not needed for that specific page. For example, do not load homepage-specific scripts on pages other than the homepage. Use Cloudflare or another CDN for frontend asset delivery Minify all static assets through Cloudflare or locally if using a separate CDN Avoid including any unused CSS rules in final stylesheets delivered to clients (cough tailwind cough) Implement basic backend caching. Use "defer" for scripts. Load non-required scripts (ex. Twitter Pixel) deliberately late in the pageload order so that they do not interrupt the user experience
Configure expires headers and etags Trim and minify markup Implement a Lazyload technique for iframes (Ensure this is not noticible for the user) Utilize hardware acceleration to ensure animations are smooth Implement other basic jank-free techniques
Implement advanced jank-free techniques Strategically load font files asynchronously (allow FOUC, or hide content) Implement an SVG sprite instead of serving them in markup Implement object caching or other pinpoint caching methods (be careful to avoid too much caching) Implement Cloudflare or other edge distribution for markup
Server setup is going to dictate much of these measures. This assumes we are using our own server. Strong passwords when passwords are used. SSH-only webserver access. Avoid using root users on webservers. Sanitize user input. HTTPS throughout the request chain Implement Cloudflare Ensure there is a plan in place to keep servers patched and safe over time (even if we are not going to do maintenance work) Avoid sending client passwords by email. Invite to 1pass. Implement two-factor auth all the time
Ensure basic firewall is in place (fail2ban) Hide system files below web root Avoid using 777 permissions Log and monitor login attempts
Disallow remote access to database Change admin passwords on a timed interval Implement server monitoring software to alert us of unauthorized requests
Do not use public DNS
SEO (Public-facing sites only)
Avoid all 'black hat' SEO practices, such as keyword stuffing, dark user patterns, unneccesary linking, redirecting legitimate site errors, domain spoofing, etc. All SERP identifiable pages should include: title tag, meta description, og:url, og:author, og:site-author, og:image Pages that should not be identifiable by SERP should use robots.txt exclusions to prevent them from being crawled. Core page content should always initially load with the DOM. Shadow DOM elements should never be relied on for SEO values. Do not use the "keywords" meta tag. All links, including those in content, use https protocol (when available) All images should use alt text and title tags. Clean, semantic markup Clear titles for all pages Meta descriptions for all pages Clear H1 on all pages Sitemap set up and submitted to webmaster tools Standard robots.txt for relevant backend system Robot-friendly backup content for JS-powered features Basic sitemap
Nuanced sitemap including pinpoint priority values
schema.org/ JSON page representation Strategic use of nofollow for pages we want to exclude
Fit & Finish
Avoid text spilling out of containers Avoid element collisions at awkward responsive sizes Avoid pixelated/stretched images Use SVG for icons and vector graphics
Ensure that webkit font smoothing is set to "antialiased", but not for reversed text Ensure consistency between colors used. Try not to use close but non-matching colors Ensure that retina screens receive higher-res imagery Ensure that hover and touch "down" states are present. Should be simple and helpful. Create smooth, simple transitions for animating elements
Add custom shadows to modify font hinting for particular cases
All files need to be organized logically into folders that represent different features or code types. Code must be straightforward and easy to follow. Code must include basic comments All code must be in version control and managed with the Git Flow methodology. Project should have a README.md file with local installation instructions
Strong comment coverage across most frequently-used files All changes should be reviewed by another team member through an MR workflow CSS and JS should be linted automatically
Unit testing Automated CI
Specific browser required for client
Latest Chrome (Mac/Win), Latest FF (Mac/Win), Latest Edge (Win), Latest Safari (Mac), Latest iOS safari (iPhone SE, 350px screen-size, and above), Latest Android Chrome. Non-bleeding-edge versions of same browsers should be supported so long as they support all features used heavily by the site.
IE11, by specific request of the client
Other specialty browsers
Project should include a documented, straightforward build process that will run on most machines without many changes. Use standard tools that most people have. Build process should cover the basics of working on the site. Build process must take under 3 seconds to run on a standard machine.
Build process includes linting, deployment, or other helper functionality
Build process integrates automated testing
Build process uses custom-coded steps in a script or extension that perform advanced functionality required by the specific project
Images should be responsive, with at least three different size variants available for most images. Images must have alt text and should likely have title tags.
Images are lazy-loaded. Images are served in next-gen formats when supported by the browser. Images should be stored on external storage like S3 so they can be more easily shared between environments.
Images should be served with an advanced script such as Imgix.js to ensure that they are loaded at very precise sizes for each user’s machine.
For projects with design comps, we always expect that any final comps are obeyed. In all projects there are grey areas, since comps cannot be responsive, and cannot possibly display all application states, so frontend devs are expected to use good judgment in extending the design team’s intent throughout the full site experience. The exceptions are when:
- There seems to be a mistake in the comp. In this case, clarify the mistake with the design team and proceed with the way it should be.
- The design is inconsistent in some regard (ex. two blog posts have different font sizes), making it harder to modularize code. In this case, speak with the design team about your concern and validate with them that it’s okay to consolidate or modify styles before doing so.
- The frontend team sees an opportunity to create a cleaner codebase or improved user experience by modifying the design. Sometimes in their zeal designers create impractical solutions that can be implemented much faster if tweaked. All team members should be able to "stop the assembly line" and flag concerns with one of our products. In this case, bring up the concern with the design team and project manager, and if a modification is sensible, we’ll do it.
Other than that, please pay very close attention to detail in frontend work. Comparing the comp to your frontend at the same screen size, any differences should stem from one of the above reasons.
Changes to our standards should be done by consensus of the group.
Any individual can recommend changes to the group. They should do so by writing a message in the Development project in Basecamp with the requested change. If nobody says "No" and at least one person says "Yes", the change is approved. Everyone who does development for us needs to meet the standards, so every developer is invested in thinking about and reviewing changes when they happen. If anyone says "No", discussion should continue until they either say "Yes", or we reach an impasse. If we reach an impasse, the lead artisans (@Andrew Heins and @Brian Kuperman) should make the final decision, taking into account all factors and opinions stated.
Different departments have slightly different focuses (for instance, the support department is more affected by security policy). Any change should be especially validated by the people who will be affected the most. Similarly, different developers have different specialities. Domain experts should have more of a say in the discussion on any particular topic, but that should not exclude newbies from being heard and respected.
As a business, we often don’t get to make decisions the way we would if profit were not a factor. Please keep in mind that our choices must be practical and pragmatic relative to the way we work with clients.
Please note that these standards are not going to match any individual team member’s own preferences 100%. They are about having a common shared understanding, not necessarily doing things exactly the way any one person prefers. Principally, this is not "the way Ty likes things done". This must be based on the shared logic of the whole team in regards to how we can do our work in a way that exceeds our user experience standards while satisfying business needs.