Closed martin-wintz closed 9 years ago
Source files contain %
and not px
. I think it makes huge difference on your statement
Sorry, fixed the typo. No, it doesn't affect the rest of my statement at all.
Sounds like oocss isn't for u @MaybiusStrip. I've been designing with it the last few months and have reaped a bit more speed and clarity of thought.
I think the only downside to oocss is html w/ more stuff in it. But you get over that pretty quick when you get in this flow of abstracting styles down to their fewest parts and assembling them when and where you want.
It doesn't "tightly couple your document structure and your style guide" like u suggest. Yes you're adding more classnames to more html elements, but so what. In fact, debugging gets a boost here cause all you have to look at is the html. And there are other kinds of problems that can fester via a more conventional css approach. Plus, if you had to redesign a site built in oocss, the same editor plugins u say could help you add inline styles could help you adjust the current styles just as easy (watch this brief screencast of mrmrs putting together a colorful page in a few minutes). Or if ur like me and a little less automated, redesigning an entire site would probably be as laborious no matter what approach it was built with.
Anyway, I find that the real crux in being a designer is to learn the language of and build trust in the styesheets I'm using. The edge I find in this library over say bootstrap is that I speak css more than I do bootstrap. Libraries like this really unleash the power of native css.
The idea here is to come up with a stylesheet that more or less accounts for any morsel of style that might be useful. Then ur free to just design. It's like @AlbertEinstein wearing a different instance of the same outfit every day to negate the need to figure out what to wear.
But you'd want it to be modular, like the unix or node philosophy where a thing does one thing well, so you don't have to be super weighted down in unused classes. (It's worth noting that there are components in the library that are made from more than one style btw.) Libraries like Tachyons & Basscss provide that. Plus it's all a build process anyways, so you can be as lean as your doc design allows you to be.
A couple things to point out about the insight/value from cats like @mrmrs & @jxnblk:
read this:
Styles should be open for extension, but closed for modification. Avoid styles that require overrides elsewhere or are highly specific to context.
and:
Abstract styles to their most essential form first. Content-agnostic, modular styles allow for design flexiblity and have a longer lifespan. Highly reusable styles can be widely adopted
Ultimately, it's a part of the rich ecosystem that we all benefit from and are free to ignore.
ps
(watermeowlon)
I don't care to get into a debate beyond Tachyons. There's a very simple question here that I asked which you did not answer: what is the difference between Tachyon classes and inline CSS? Inline CSS is a known anti-pattern in design, so why is hiding it behind some confusingly named classes all of a sudden an awesome thing?
It don't need to look any further than this framework to see that whatever principles it stands by are neither re-usable nor scalable. What if I had hundreds of success buttons through a large app that had the tachyons class "blue", and I decided I wanted all the success buttons in my app to be green? I can't even do a search and replace for "blue" to "green", because I might have used that class elsewhere. Can you explain how that is "dripping with reusability & scalability"?
This is why bootstrap uses "btn-info" and "btn-warning", so that you can change their colors in one place without breaking your abstraction.
@MaybiusStrip
This is a great question. I do have some rationale on how I see them to be different. What I think most people mean by 'how is this different than inline styles' -is in reference to the text-editing workflow. In that respect you still have a 1-1 relationship between elements edited and visual styles. So yes they aren't too much different.
One major difference is that inline styles do not support media queries or pseudo elements. This alone is a huge advantage of using css as I always need those for every site I build.
There is also a real difference is in how the browser renders the code. Inline styles are 1 to 1 for the browser. i.e an inline style can only style one element at a time. While a class has a 1 to many relationship. This has non-trivial deltas in rendering speed and can greatly reduce jank in a complicated ui.
That is from a browser performance angle. I find it advantageous from a readability standpoint to codify certain things. I agree typing inline styles is not a pain and something a good set of text-editing skills can easily handle. Setting multiple font-sizes on an element with tachyons is as simple as
<p class="f4 f2-m f1-l"></p>
This for me is pretty easy to memorize after a brief ramp up and very readable when I am trying to modify the font-sizes of this header in the future. Granted I also wrote the code. But I wrote the code based on how I think. And how I wanted to work while designing around content in the browser. Which is a pretty specific problem set so - it might not prove to be useful for you. And that's okay. But in the world of inline styles - I would have to memorize padding and margin scale values. In a codified system I can have name spaced size classes like s,m,l,xl. And I can change those scales across projects, but still only have to think in a naming system that never changes, regardless of the baseline scale.
I hope this answers your question on why they are different. If it does not - please let me know of any thing you want more clarity on and I will try to be more thorough in my response.
To a few of your other points: So, Tachyons is largely founded on my experience refactoring many large scale css systems. I think a great weakness in much of the css I see written is that it is very hard to redesign a site without doing everything from scratch. And it's also very hard to reuse things because people mix concerns a lot. Single purpose class structures in my experience make this process very easy as you don't have much digging through code to see what components are tied to what pages and how they might change contextually... By encapsulating the work in an individual block of html - it is very easy to refactor something with the confidence you aren't breaking anything else. In my experience the inability to change code without knowing you are breaking something else you can't see is one of the things I see slow front-end developers and dev teams down the most.
"You lose the flexibility to change the properties of multiple related elements at the same time:" I disagree with this. If it's a known pattern you are trying to change across many pages - that is a text-editing or templating problem in my mind. But even in a single purpose class architecture if you change the class - you also change it everywhere that class is defined. So you can update your spacing scale, or your color palette, or your type scale - and that will propagate everywhere. Those are valuable couplings in my mind - and they are retained in this architecture. Harry Roberts also brings up a good point that if you have a common html pattern on hundreds of pages, it should most likely be a component that is included within a templating system. And you should have to change it in hundreds of places. To me this problem happens way less often than "I need to change 5 things on this interface right now and I am not working on any other part of the site" That is more reflective to me of web development at any large company. Encapsulation is your best friend in that scenario.
"You clutter up your DOM with styling directives"
This is true. But I don't have an argument for why that's bad other than that it is stylistically ugly. Which I agree with. But it's fast to render in the browser. And it also has helped me get dev teams to build responsive interfaces more quickly. And those are the things I care about. Dev velocity and application performance.
Let me know if you have any other questions. Thanks for opening this issue. I've been meaning to write more about this as it's a very common question that I had at first as well when I saw oocss. It won me over when I tried to prove it wrong and did a bunch of performance testing and found they way I originally wrote css was very bad for performance on several fronts. And then I started building websites faster and I liked that too :)
@brianzelip - Thank you so much for the nice words. Really appreciated your thoughts on some of the ways Tahcyons / Basscss are helping you out. Would love your thoughts more on what you like and don't like about Tachyons as I'm trying to make a bunch of improvements at the moment. Feel free to ping me anytime with any type of thoughts. Doesn't need to be well structured or anything.
You make some great points about essentially maintaining 'dependency injection', and Tachyons does seem fairly groovy for purposes of rapid prototyping (provided you 'learn the lingo') and maintaining generally untangled and self-explanatory code.
But surely you'd tend towards a more (conceptually, language-agnostic) OO SCSS approach to consolidate the more complex and reusable patterns you use... at least to save the time and headache of having to search and identify instances of the same asset whenever you decide to make repetitive stylistic changes?
@janbaykara - I definitely think there is a place for identifying patterns making it easier to implement them. Especially when it comes to interactive form controls - there is a place for more component based architecture. I think things are all about balance and context. While cliche - with css I still find it to be very true :)
@mrmrs Thank you for the thoughtful reply, which directly addresses my points.
If I understand you correctly, you are acknowledging the similarities between inline styles and tachyons. You point out some of the benefits of your approach, but I read nothing that is hard denial of the comparison. The way I read it, you're subverting a lot of ideas people have about CSS, which is much more interesting than if you tried to side-step the issue by denying the connection.
I disagree with this approach is a good solution to the problem you are trying to solve. Maintaining CSS, like any other codebase, is really difficult. Coming up with the appropriate abstractions is hard. Changing things when you abstractions are broken is scary. But you're just replacing it with a slew of other issues by taking this approach.
Refactoring should not be a text-editor problem. When you change a class in one place and it propagates to all the elements that have that class, the browser's CSS processor is proof that your change was effective. Whether you're a grep wizard or not, there's no such guarantee of the correctness of your changes when you use a text editor. I would never let anybody on my team do a search and replace on the hundreds of markup files in our codebase without some serious, time-consuming supervision.
To make a javascript parallel, this would be equivalent to writing a function calculateSalary(employee)
as multiplyBobsHourlyPayByBobsHours(); multipleyJohnsHourlyPayByJohnsHours(); etc...
because the former is too reusable, and when you change it you affect too many other functions that are dependent on its API. But what happens when you want to add an employee? bonuses to the salary calculation? Then you need to do all sorts of dangerous text editing to rename all your methods so that they stay accurate. On the other end of the spectrum, you can definitely write functions that do too much, or that are used too many degrees of separation away. So I agree that small is good, but literal is not.
The problem is that CSS is given second class treatment to "real programming" in large codebases. While the javascript gets code reviewed, unit tested, constantly refactored, CSS is almost never given that much attention.
But I know it's possible to write clean abstractions that you can feel safe about changing, because bootstrap and other frameworks like it do it. They're able to do it because they literally have a team who's only purpose is to build maintainable, cleanly abstracted CSS, as opposed to rushing to keep up with an engineering team by slapping CSS wherever is most convenient.
I get the benefit of using this for rapid prototyping, and I'll relent that it might have some benefits over inline styling, but actually using this in a large production website seems dangerous and irresponsible.
@MaybiusStrip -
Thanks for your thoughts.
I am curious as to why would it be "dangerous" and "irresponsible"? I have used this exact css architecture in a few production environments and so far nothing bad seems to have happened that I am aware of.
Refactoring should not be a text-editor problem. When you change a class in one place and it
propagates to all the elements that have that class, the browser's CSS processor is proof that your change was effective. Whether you're a grep wizard or not, there's no such guarantee of the correctness of your changes when you use a text editor. I would never let anybody on my team do a search and replace on the hundreds of markup files in our codebase without some serious, time-consuming supervision.
I agree with part of this - but don't understand how this problem is mitigated with css architecture. If you want to change the design of 100s of pages - I have never seen that not be a serious undertaking regardless of your css architecture. In my experience though - it is easy to change hundreds of pages of built with single purpose classes than it is to change small projects with component based architecture. I only have my experience to speak to though. I have been building website professionally for about 8 years and I have never had to change a button or a similar component on 100s of pages. This seems like poor front-end templating architecture in my opinion. One note - all code authoring is a text-editing problem. Your command over how quickly you can make arbitrary changes to a given block of text - is all that really matters in the end.
But I know it's possible to write clean abstractions that you can feel safe about changing, because bootstrap and other frameworks like it do it. They're able to do it because they literally have a team who's only purpose is to build maintainable, cleanly abstracted CSS, as opposed to rushing to keep up with an engineering team by slapping CSS wherever is most convenient.
I disagree with this. I have worked with the core bootstrap team - and one of the difficult things about working on bootstrap is making changes that don't break any existing components or architecture. It is not a seamless process to upgrade between versions of any css or front-end framework that I know of especially Bootstrap. Bootstrap is great but it is trying to solve a different problem set than Tachyons is.
Hmm, I disagree with you so fundamentally on some of these points that I don't know if we could come to see eye to eye, especially not over asynchronous communication. You're clearly thoughtful and knowledgeable about what you're doing here, so I'll just agree to disagree. Really appreciate the response though.
@MaybiusStrip - likewise! I'm comfortable agreeing to disagree :) But you bring up some good points and just wanted to share my point of view.
The advantage of using classes instead of inline styles (even for very small things such as float-left
) is primarily to avoid specificity hell. Also I think it enforces modular thinking when writing components. Sometimes your component doesn't have to know nothing about text positioning nor color properties, that's when you can use these helpers to keep things separate.
Popular frameworks such as Bootstrap and SUITCSS use this technique quite a lot. I've learned to love it .
There are a lot of words here, but addressing the OP directly with no further context...
How is having class="mw-50" different from style="max-width: 50%"? Same goes for the majority of classes I looked through in the css file. I cannot think of a difference other than a cosmetic one. I would argue that the latter is easier to read and remember, and just as easy to type with the right text editor plugins.
The most important difference is specificity—inline styles trump classes.
You tightly couple your document structure and your style guide and therefore make it much more difficult to maintain. (Imagine doing a complete redesign of a website built with tachyons, or a css-zen-garden where the template was built with tachyons)
Plenty of folks seem to miss the fact that when you're doing a complete redesign of a site built with literally anything, chances are you're going to rewrite everything :laughing:. (Not really an issue in that extreme example, but I feel you.)
That said, I imagine you'd combine this with something else. From the looks of it, Tachyons is mostly utilities and shorthand. It doesn't account for your custom navigation, for example, but it can help with it.
You lose the flexibility to change the properties of multiple related elements at the same time
With some property values, sure, but that's also a helpful thing at times. I see it all too often when folks try to create relationships between things that are much better off as unrelated and without shared code.
You clutter up your DOM with styling directives
Yeah, no way around that it seems. This is just a different way of doing it though—put it all in the HTML, or put it in the CSS. Or both.
Tachyons almost seems like a performance art piece in that it takes an idea to a rational extreme. To me it looks like the idea here is to build a CSS "framework" that is as performant and compressible as possible. It also seems like it grew out of other work. Other frameworks or methodologies might encourage authors to balance CSS performance and size against maintainability. Tachyons is an extremist; it's the Weather Underground of CSS frameworks :smile:
It's also clearly the work of a VIM user. I'm not a VIM user, but among the VIM users I know there is a fierce sense of how efficiently they can move blocks of code around. Personally, I keep thinking I want to learn VIM so I can be as badass as them. I'd imagine that some of the maintainability gains one gets from abstraction strategies and Sass's @includes
and @extend
directives can be met keystroke for keystroke by a seasoned VIM user.
Not trying to make a judgmental comment here, though it kind of reads like it. Tachyons is a wildly different approach when compared to other CSS frameworks, and I hope to see better examples, documentation, use cases, or whatever else comes out of the up-coming period of work. I'm going to try to set aside time to bang on it and see what it's like...
We recently began overhauling our approach to writing Sass/CSS where I work, and the conceptual frameworks of Tachyons and Basscss provided a lot of the inspiration. I've found that, while breaking designs down into these sort of micro-classes does make for wonderfully more "messy" html, developing and iterating on designs seems to come much faster. It also allows non-front-end developers to better understand how components are styled and how to edit them if need be (providing our naming scheme is easily comprehensible) without having to dive into the CSS itself.
One twist we’ve added is that, if we find ourselves constantly applying the same series of single-use classes to same sorts of elements, we’ll then create a component class incorporating those single-use classes. We try to keep these as content-independent as possible (both in the styles and in the naming) to encourage reuse, though.
I think one big difference between single-use classes and inline styles is definitely the ability to incorporate responsive design patterns into them with the use of media queries. Doing this as inline styles would be a huge headache.
@mdo - I facepalmed pretty hard when I realized I missed the point about specificity. Wise words as always.
Also +1000 this:
With some property values, sure, but that's also a helpful thing at times. I see it all too often when folks try to create relationships between things that are much better off as unrelated and without shared code.
@mrmrs Agree. As I've said above, specificity is the primary/out-of-the-box benefit of using this kind of approach!
Inline CSS is also bad because printing the page or disabling style sheets would keep these inline style directives.
@MaybiusStrip I know your statement is a couple of years old, however plenty of large companies are using this in production. The idea of inline-styles being bad is an artifact from the days of html where you had static html and every page had it's own header / footer copy (or similar html & modules were duplicated on multiple pages). There's nothing inherently wrong with inline styling on an item that's used once, twice. The problem today is that more and more, pages are becoming like applications in that no two pages look alike. Now... you could write css for these pages, however you'd be going through the trouble of creating classes that are unique in nature and highly unmaintainable (and separated from where the content actually is).
Facebook uses inline styles, and it would be hard for any company to match the scale that Facebook operates at. Are there downsides to using inline styles? Sure. However it doesn't suit us to talk philosophically about the original purpose of css, as the original purpose of javascript wasn't to make applications. So we're better off focusing on the now, and why Bootstrap (Twitter) moved in the direction of placing the abstraction in html (classes), why facebook is placing the abstraction in the html (inline styles). I can elaborate on this further and explain the reasoning behind it if you're interested... I understand the rational fully as I had the same thought but quickly came around.
Fascinating discussion, thanks to all for sharing. As an experienced frontend developer, I've found myself naturally progressing to utility classes more & more as I work on larger and more complex projects, and so now I'm taking a good look at Tachyons and BassCSS. If anyone's used both, I'd appreciate some opinions on which they thought was better suited (for them). Also, beyond what these libraries provide, how are you approaching styling components? Just using regular hyphenated class names, or are you mixing in some OOCSS/SMACSS/BEM semantics? Interested to know. Thanks in advance.
@niallobrien I’ve not used BassCSS since version 3 or 4 (I think?) so my thoughts may be a little outdated. However I recently used Tachyons to rebuild my personal site and my blog so I have some recent knowledge on it.
I found BassCSS a super friendly way to get started with building interfaces with low-level/atomic/functional/whatever classes, primarily because of 1.) the more 'verbose' class style (table-cell
vs Tachyons’ dtc
, for example), and 2.) what feels like a relatively more compact surface area (which is nonetheless super flexible and capable) which I found easier to learn. Once I began to fall into using these sorts of patterns of thinking, and as I developed my own similar libraries for my day job, I found myself wanting to get away from the longer class naming. This is when I started using Tachyons for my personal work.
To me, Tachyons feels like it’s one step deeper into the atomic CSS mindset — the surface area is larger (visible just by comparing Tachyons and BassCSS on CSSStats) and I feel like somehow the more concise class naming is more inviting to people who are already sold on this way of working (this is a very personal opinion and likely won't be applicable to everyone). I also think that, while both projects offer top-notch documentation, Tachyons’ component gallery does an amazing job of demonstrating just how much can be accomplished with it.
In short, for me, BassCSS provided the perfect entry point to working with low-level classes, while Tachyons then gave me something that feels like Unix for CSS.
(Again, this is all personal opinion, and I don't mean to suggest that one is more or less proficient or suitable than the other. I’m sure Adam and Jackson can speak better to any differing philosophies or intents.)
As to how I implement classes outside of the libraries, I try to follow the conventions used in Tachyons — memorable acronyms where possible (e.g. mt
for margin-top
), explicit property names where it makes more sense (e.g. relative
for position: relative
), and numbers where I’m describing something in a scale (e.g. pr2
for `padding-right: <2nd step in scale>). I haven’t found much of a need for any other methods.
(IMO, OOCSS/SMACSS/BEM naming conventions clash with systems like Tachyons/BassCSS, since those architectures prioritise component-based systems, where in Tachyons/BassCSS/etc, components are composed from more atomic units, thus negating a class naming system where something like .button__icon--active
or even .media
would ever be used.)
Thank you for your fantastic comparison between the two @colepeters. I feel that I'd be able to get into Tachyons a little easier if the documentation were clearer. It seems that I have to do a lot of clicking around to see examples of how to use the classes etc. and although the homepage says "responsive grid" I can't seem to find a page documenting it (I might be blind). A single page listing the classes with an example of their usage would be hugely beneficial imo.
@niallobrien What is not currently clear for you about the documentation? Don't think we could document everything in tachyons on a single page but we'd definitely like to make things pretty clear. Some more specific problems you are having would be super helpful for us if you have time to write them out.
@niallobrien Here is a list of places we document various options for grid usage
http://tachyons.io/docs/layout/clearfix/ http://tachyons.io/docs/layout/widths/ http://tachyons.io/docs/layout/display/ http://tachyons.io/docs/layout/spacing/
Examples:
Hi @mrmrs - thank you for taking the time to reply & provide relevant links. I think the problem for me is compounded by the fact that you had to post a list of links instead of one or two. I understand that a single page of all classes and examples might be a bit much, but perhaps a single page highlighting the key classes users would use (with examples) and links to further info would go a long way. For example, the http://getskeleton.com and https://milligram.github.io homepages display the basics up front (typography, grid, buttons, forms etc.) which makes it super-simple to get going quickly. Of course, another obvious comparison is BassCSS which does the same, though of course it doesn't have to cover as much up-front as Tachyons would. In the interest of fairness, the BassCSS docs are just as cumbersome once you pull in all of the other extras (see https://www.npmjs.com/package/ace-css). As a new user, I feel like I need a Tachyons cheat-sheet or something, to have at my side (or open in another tab). I hope that explains my perspective a little better? Regardless, eager to dig in and learn as I've found myself gradually moving towards utility classes over the BEM component model.
Thanks for a really fascinating thread and for all the work on Tachyons! Thoughts below but one question up top. Do you plan on adding extra media query breakpoints to Tachyons? I find responsive design takes more than three for the applications I work on. Very happy to help out converting things if you wanted it.
@niallobrien if you are looking to get started with Tachyons, and remain overwhelmed by the documentation, my two cents suggestion is to pick one area you use a lot (for me it was margin and padding). Just start using that and see how you get on. I think once that one module clicks with you, the rest will fall into place much faster.
Over the last year I've gone from Bootstrap to Bass, to homegrown variants, to now thinking Tachyons has just about everything I need. The OP sees Tachyons as an extreme, which it is, but while Bootstrap makes heavy use of components, it also uses a lot of utility classes. There are obvious ones like "pull-left", but the grid system itself is modular / granular. To get a responsive, complex grid working can take 5 classes or more on each of several layers of nested divs. This modular approach got me reading much more about OOCSS then tachyons/basscss approaches.
I agree with others that prototyping with Tachyons et al is fast, easy, and takes less typing / mental energy. I see two big benefits of the approach to longer term CSS management:
Not a benefit, but not a con either. How many times using component based CSS have you had to look at another similar page to work out exactly what the HTML/CSS structure and classes should be? I do it all the time. Looking up what two special divs with their component classes to use and copying them takes no less time than copying two divs with a handful of utility classes.
Finally, at work I find myself designing new classes now in a generic way - if one place needs something special, if I can make a generic utility class I will. It makes the page and CSS easier to reason about and can help elsewhere too. Utilities I have found helpful are ones that target child elements - eg .child-pa0. In a legacy application mixing server side and client side rendering with HTML, sometimes odd classes like that are the only way to get the page how I want. Have any of you had any experience doing that? I'd be interested in any thoughts.
Thanks @lanyip - you raise some very great points and problems I've ran into when taking the BEM component approach. For now I'm going to add a lot more utility classes to my own Stylus framework (http://niallobrien.github.io/stylus-ui/) and make a gradual transition to utilising these classes more & more. I don't need anything too complex at the minute and am happy with the BassCSS syntax on top of my BEM approach; for example, my grid with media query modifiers. Hopefully I can gain the confidence to then move to Tachyons, but right now I find the documentation very overwhelming (like you said, I should probably start with learning the grid).
@MaybiusStrip the biggest pro IMO for using functional css is following:
I know what a CSS class changes in the UI.
Doesn't seem to be very important at first glance, but it's hugely helpful while developing. If I see classes like btn-default
than it's great to know that those reference button styles, but I'll never know what those styles actually do (unless I have a look at the source code). And when I would like to customize the appearance I would waste time by
I can tell you that functional css in combination with a good component / templating library has sped up frontend development quite significantly for me.
fyi the app I used it on is used by big companies without any unexpected problems
I love that this discussion is still current after 4 years! I just found out about Tachyons this week, and am intrigued by it. But how is the situation handled where you have say a bunch of "cards" and you want to change border-radius
? Wouldn't you have to change every instance from say .br1
to .br3
?
Is the difference between this and say Bootstrap that, with Bootstrap, the classes you use create components out of your markup, where with Tachyons/BassCSS, it's expected that you're using a templating system to create your own components, and then including them in your pages with, for example, a custom <card>
component? Can someone perhaps give an example of how you'd create something like Bootstrap's .well
class with Tachyons and the markup you'd use if you knew you'd need a few different wells with different background colors?
@jdhines these examples might be of help for you: http://tachyons.io/components/
@matteodem: thanks. I did see the components page before, which actually brought up this question in my mind, because it's just markup, so if I wanted a button:
<a class="f6 link dim br1 ba bw2 ph3 pv2 mb2 dib navy" href="#0">Button Text</a>
And if I want to change this to use a different color, say changing my "navy" buttons to "black", wouldn't I have a ton of places to change this? As opposed to say a class of .btn-default
where I would only have to change the style in the CSS.
@jdhines You are definitely right that you would have to a global search and replace to change the color. If you can know for sure that you have the exact string of classes in the same order then a find and replace will work fine.
Personally, I think there is a case for some standardised component classes for large complex projects. If you know all of your button classes will be the same for every button, a component class makes sense. If, on the other hand you are switching your branding colors, then you could use a "brand-highlight" class everywhere -this would be navy now, and then you could change it to black.
PS Bootstrap increasingly is using utility classes, and if you look at its grid system, while each class does more than one thing, to create a proper grid you can require a large number of classes on any element, as well as its parents
@jdhines it very much depends on how you structure your component / templating system. If you are just using static html and need to change all border-radiuses from br1 to br3, I'd suggest using find and replace. You could essentially still make the change in one spot.
As far as your button example, again you wouldn't necessarily have more than one place to change this. Regardless of your css architecture, if you have a block of markup that you are reusing lots of places, you should probably make it a component. But even if you are just managing static html with - in my experience I rarely if ever have just one button style for a site. So just changing one class called btn-default wouldn't be enough to handle covering all of my button designs. If you checkout something like http://land-book.com - I think you'll find a lot of simple sites have multiple button styles just on their landing page.
The counter example is what happens if you have btn-default but need an additional two button styles? What do you do? That is the scenario I run into most often. In this architecture, the power is in the composability. The benefit is that there are a large amount of button styles you can generate without writing any css. If you know your site only requires one button style, a btn-default class sounds like a great solution for you. I just find I generally have no idea how many button styles a site is going to need.
@mrmrs This is a great thread spanning a long time! I thought I would share my thoughts some points as I am looking into using Tachyons as I really like the idea of it, the main reasons for me would be -
Like others on here there are few things that are not great for me:
I am going to try it for a smaller project that I will develop on my own but want to try it on some large projects where I am part of a large team. The large projects are using Bourbon & Neat currently some in Wordpress and some in Jekyll, my thinking is -
This is where I see Tachyons being super helpful as to get the benefit of using it for the main parts (excluding grid) and then the few repeated styling parts we use custom class names, potentially using a similar naming convention.
I really like the simplicity of Tachyons and think it is part of something rather than the whole of something - can you see that working?
@gosupernova This seems completely unrelated to the original thread which is centered around the differences between inline styles and single purpose classes composed in the html. Happy to respond if you open up a new issue or ask these questions in our slack. Thanks!
Having just recently ran across tachyons, I found this thread extremely interesting.
I really like the ideas behind tachyons, but I'm extremely anal about not cluttering up my classname attributes.
I'm getting around this by combining tachyons-js with styled-components. Here's how I put together a few of the list templates from the tachyons.io component page.
https://gist.github.com/pward123/0c67499fdb07117eae29b53d17253e53
Thanks for creating such a great tool!
Just thought I'd say that this has been a great discussion.
Also wanted to say, I really enjoyed reading this thread. I find it fascinating that this age-old (in internet years) discussion is still super prevalent today. Being part of a team responsible for building and maintaining a large-scale design system myself, it's somewhat amusing that despite all initial intentions, we keep returning to utility classes like tachyons'. It felt dirty to begin with, but since we now use React, we hardly notice the HTML output is messy. Sometimes I wonder why we didn't deliberately just go all in to begin with, as we now have a mixture of approaches. The biggest pain point for us is that we never anticipate every use case when creating styles tied to components. Context changes and suddenly alignment is off, for example. We now tend towards offering as much flexibility as possible within a defined set of parameters (ingredients), and rely on designers choosing the right kind of 'salad' to make for the situation, instead of trying to dictate it 100% of the time. Branding remains fixed, but the rest is just championed via best practice (recipes), not hard and fast rules. Okay. Maybe I took that analogy too far.
Like the original poster I, too, had an allergic reaction when I first encountered this approach. It runs counter to years of best practices. But I've come around to seeing its advantages when used in conditions that recent technologies have enabled. The context for my comments is in a system where many developers are contributing to a large code base.
To answer the initial question, no, it's not unlike using inline styles. Though philosophically, couldn't all classes could be considered as aliases for groupings of inline styles? Functional CSS takes it step further by breaking that class alias button
into multiple aliases f6 link dim ph3 pv2 mb2 dib white bg-black
that are single-purpose enough to be combined to form any UI element.
Benefits
data-id="todo-list"
. Having said all this I would only use functional CSS on a large-scale project if I had in place a templating system to abstract my classes into components. As commenters already pointed out I don't want f6 link dim ph3 pv2 mb2 dib white bg-black
duplicated in hundreds of files, requiring error-prone find-and-replace exercises. But if these classes were contained in, say, a React component <Button>
then I've removed the issue of duplicated code and I get the benefits listed above.
I'm still new to tachyons, but I don't see it as the same as inline styles at all. The key for me is really that inline styles do not allow for standardization or abstraction. It is quite possible to be both atomic and semantic at the same time. You could create classes such as color-danger
, color-success
, etc.. to approximate bootstrap.
However, it seems to me that proponents of this approach would favor names based on visual appearance rather than more semantic naming. I would prefer semantic naming where possible, but I don't necessarily think a library such as tachyons should extend into defining those semantic abstractions for me. Separating standardization from abstraction allows for complete design flexibility without losing that standardization.
Going further, as a general rule I don't think it's good idea to repeat the same classes over and over again in html. So this can either be solved with templating or with css. My instinct is to add an additional layer of abstraction to the css. I would prefer to define a composite rule like the below than to deal with this in templating or just resigning myself to mass text replacement. Concerns about reuse and contextual differences apply to templates as well and we all have to decide where to best make abstractions.
.btn {
.f6
.link
.dim
.br1
.ba
.ph3
.pv2
.mb2
.dib
.black
}
Once post-processed this could ultimately transfer fewer bytes if all of those individual classes would otherwise be repeated enough. 10 occurrences of .btn
in the stylesheet vs f6 link dim br1 ba ph3 pv2 mb2 dib black
* the number of buttons of this style that appear in your markup. Nor does it increase specificity. Also the individual classes are still there if you wanted to use them individually and vary them. So I agree that you can't capture all the variations nor is it a good idea to do so, but I think there are plenty of frequently repeating combinations of visual styles that can easily be grouped like this to get the best of both worlds.
First time I'm seeing this framework, yet I've been "using" Tachyon for years. In my head it's a LOT different from inline styling, both in performance aspects and also philosophically if you don't abuse it. Too much abstraction or specificity will defeat the purpose. This means avoiding the use of color names or padding/margins in most cases or you end up with names that don't add up or even worse, override hell.
Semantic names still win out for designing edge cases, and visually I'm fine with mixing both as long as semantic names come first. Here's some code from an actual app. I've got my own naming convention but there is a lot of similarity:
<div class='gallery grid-100 p-20'>
<a class='shaded fl m-10 bo-1' href='/image.jpg'>
<img class='db mw-100' />
</a>
</div>
Conclusion: After styling dozens of websites like this, it's pretty amazing how far you can get leveraging a core library of functional styles. I'm often 80-90% of the way there before I need to start plugging in the custom styles. It may upset some purists, but it's a heluva lot DRYer and easier to debug/update than the mess of spaghetti classes I used to work with.
I keep reading that Atomic CSS can solve the problem of 'specificity hell'. I'd like to point out that this is not necessarily so: As soon as you apply more than one class to an element then you are introducing a potential specificity problem. This is because the declarations in one rule set will override those in another if it appears later than it in the stylesheet. For example if I have the following styles:
.foo {
border: solid 1px red;
padding-left: 10px;
}
.bar {
background: green;
padding-left: 20px;
}
And I apply both classes because I want to have a green background and a red border,
<div class="foo bar"> ... </div>
then the padding-left
property in the .bar
rule will win out as it appears later in the stylesheet.
The only way to avoid this problem is for each rule set to contain only a single declaration e.g.,
.foo {
border: solid 1px red;
}
.bar {
background: green;
}
so that it's clear that when I attach the class foo
to an element then I am only adding a red border and nothing else, and when I attach the bar
class I am only adding a green background. As long as this convention is practiced and understood, no nasties should lie underneath. But yes, this is really the same as inline styles. (Some will say that inline styles are different from classes in having greater specificity. This is true, but remember that specificity only becomes an issue when you have two declarations that apply to the same element. Specificity only becomes a problem when you mix methodologies - e.g., using classes and inline styles)
I continue to use this style in production with single rule classes. I believe there is a place for components too but my default is single rule classes. My class list continues to evolve: every time I face a new styling need I attempt to make a utility class (eg for filters, box shadows, borders on hover, and so on). This is DRY, creates easy to maintain CSS and ultimately less CSS. It also makes it far easier to have a single CSS codebase across multiple sites/products.
How is having class="mw-50" different from style="max-width: 50%"? Same goes for the majority of classes I looked through in the css file. I cannot think of a difference other than a cosmetic one. I would argue that the latter is easier to read and remember, and just as easy to type with the right text editor plugins.
You have precisely the same disadvantages: