The document discusses the challenges of maintaining scalable and organized CSS architecture, emphasizing the need for a structured approach to handle growing complexity and technical difficulties. It outlines key principles for writing maintainable CSS, focusing on component independence, clear naming conventions, and avoiding excessive specificity. Additionally, it highlights the importance of collaboration between designers and front-end engineers to ensure that CSS effectively supports component-based design systems.
“I don’t understandthe cultural fascination with failure being the source of great lessons to be learned. You might know what won’t work, but you still don’t know what will work.” Basecamp Excerpt from “Rework”
Technical Difficulties Sourceorder affects application order Specificity is hard to deal with CSS operate in global scope Permissive by its nature
“Everyone else inthe W3C CSS Working Group, the group which defines the future of CSS, fits the profile of a developer much more than that of a designer.” Lea Verou
Example div.social-links { > diva { color: blue; } } Visual styles are tightly coupled with markup which makes them hard to evolve Reusability of component is limited Ambiguity that leads to growth of specificity
35.
Rule Avoid any signsof DOM elements in CSS code including references to HTML tags, ID (#) and (>) child selectors
36.
Rule CSS selectors mustconvey semantics of the component and it’s integral parts. Class selector conveys a lot, element selector almost none
Example .button { color: white; } .sidebar{ .button { color: orange; } } Component is no longer self contained entity and its visual appearance is not predictable at dev time Leads to growth of specificity
41.
Rule Component styles mustnot be written in reliance on their location on a page, instead provide location independent variations that can be used anywhere
42.
“Instead of saying- The buttons need to be smaller when they’re in the header, we need to be saying - We have a smaller variant of our buttons, and it’s these that we use in the header.” Harry Roberts
Example .filter { .filter__header { .filter__header__icon{ /* Declarations */ } } .filter__list { .filter__list__link { /* Declarations */ } } } Component is too complex which makes it hard to maintain Following that style may lead to unnecessary dependencies between integral parts
47.
Rule If CSS styleshave no dependency they must not form parent-child relationship
#4 Enforced Naming Allaspects of component definition must be named in a way to communicate their relationship clearly and protect from incorrect use
51.
.infobox /* Block*/ { .infobox__body /* Element */ {} .infobox__footer {} .infobox__title {} &.infobox--size-full /* Modifier */ {} } Example
52.
#5 Explicit States Dynamicbehavior must be implemented with state classes that JavaScript toggles. No direct style manipulation is allowed with JavaScript.
open: function (){ elements.root.show(); elements.trigger.css('color', 'blue'); }, close: function () { elements.root.hide(); elements.trigger.css('color', 'white'); } Example Visual appearance of component is now split across JavaScript and CSS which makes is hard to maintain There is no simple undo operation for setting style properties in JavaScript so previous state has to be maintained somewhere or inline styles manipulated directly
55.
open: function (){ elements.root.addClass('state-open'); elements.trigger.addClass('state-active'); }, close: function () { elements.root.removeClass('state-open'); elements.trigger.removeClass('state-active'); } Example
.state-hidden { display: none; } .infobox{ display: inline-block; &.state-hidden { display: inline-block; visibility: hidden; } } Example Component is no longer self contained which causes inclusion of override declarations In some cases may lead to a need to have !importants
#6 JavaScript Hooks Neveruse component classes to select elements with JavaScript. Introduce specialized classes just for the sake of selecting elements.
Example var elements ={ mailing_list: internal.$e, form: internal.$e.find('.social-widget__query'), submit_button: internal.$e.find('.button'), submit_button_text: internal.$e.find('span'), validation_message: internal.$e.find('.social-widget__validation-message') }; Hard to modify component styles due to dependencies in JavaScript. Makes whole component fragile
62.
Example <div class="social-widget social-widget--inversedjs-mailing-list"> <div class="social-widget__title">Stay in the loop</div> <form class="social-widget__query js-mailing-list-form"> <input class="js-mailing-list-email" type="text" name="email" placeholder="Email address"> <label class="button"> <span class="js-mailing-list-submit-button-text">Submit</span> <input class="js-mailing-list-submit-button" type="submit"> </label> </form> <div class="js-mailing-list-validation-message social-widget__validation-message state-hidden"> Email is not in correct format! </div> </div>
63.
#7 Local MediaQueries Responsiveness of a page must be based on responsiveness of each component thus Media Query must be local to a component
64.
.blog-entry { .blog-entry-body { /*Declarations */ } } .infobox {} @media @phone { .blog-entry { .blog-entry-body { /* Declarations */ } } .infobox {} } Example Code duplication makes components hard to maintain Components are not self-contained which makes the outcome less predictable at dev time
Physical Structure Single filefor all of the styles Single file with comments One file per type of styles One file per component
79.
Fallacies Use idselectors for performance reasons Too many classes is a bad thing, style based on tags Nest CSS selectors to follow DOM hierarchy Put all styles into single file all the time because it is easier to maintain Introduce lots of utility classes to have greater flexibility when styling things
#4 Всё начинается хорошо, но потом становится сложно сопровождать.
#7 Второй раз ты пытаешься хорошо писать свойства CSS, но всё равно что-то идёт не так.
#10 Interestingly, we don’t usually make this oversight with other languages. A Rails developer isn’t considered good just because his code works to spec. This is considered baseline. Of course it must work to spec; its merit is based on other things: Is the code readable? Is it easy to change or extend? Is it decoupled from other parts of the application? Will it scale?
#11 Тут важно сказать что подсознательно первое о чём мы думаем – это то что мы можем работать без плана. Но как было показано на примере это не работает! И дальше пойдёт описание driving forces.
#17 Interestingly, we don’t usually make this oversight with other languages. A Rails developer isn’t considered good just because his code works to spec. This is considered baseline. Of course it must work to spec; its merit is based on other things: Is the code readable? Is it easy to change or extend? Is it decoupled from other parts of the application? Will it scale?
#27 Требования к CSS архитектуре такие же как и к архитектуре программных компонентов -> Переход на следующий слайд
#28 Требования к CSS архитектуре такие же как и к архитектуре программных компонентов -> Переход на следующий слайд