Live data from Hacker News

In defense of functional CSS

mikecr.it

241–246 of 246 posts

Re: In defense of functional CSS

#241
post #236

Earlier quoted context omitted.

> The classList API makes modifications to the class property very easily. So does the dataset interface for custom data attributes: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement... > You'd be essentially limited to one identifier in attribute selectors. You can't really select from multiple identifiers with a data attribute… That's just not true, there's an attribute selector that targets strings in a…

I wasn’t aware of the tilde attribute selector. Still a lot more characters, though. The classList api is still a lot more suited for this than dataset. None of the modifications done through the dataset api would reflect in the DOM and be readable by CSS unless you were to convert the list to a space separated string and explicitly set the attribute. classList handles all of this for you.

> None of the modifications done through the dataset api would reflect in the DOM and be readable by CSS unless you were to convert the list to a space separated string and explicitly set the attribute.

I'm really not sure what you mean by this. If you set the data attribute any of these ways, it can be targeted in CSS with [data-demo="example"]:

    el.dataset.demo = 'example'
    el.dataset['demo'] = 'example'
    el.setAttribute('demo', 'example')
CSS doesn't require a space separated anything. When you use an attribute selector in CSS it treats the entire value as a string, spaces included. But it's not classes versus attribute selectors, as class is an attribute, and therefore also something you can select with attribute selectors.

Also, think about the asymmetry between CSS and HTML when considering saving characters, one CSS selector targets ∞ tags, so I'd rather write slightly longer selector one time, than need to use a much longer 'namespaced' value on each element where I want the style to apply. That's leveraging what CSS does best!

Re: In defense of functional CSS

#242
post #241

Earlier quoted context omitted.

I wasn’t aware of the tilde attribute selector. Still a lot more characters, though. The classList api is still a lot more suited for this than dataset. None of the modifications done through the dataset api would reflect in the DOM and be readable by CSS unless you were to convert the list to a space separated string and explicitly set the attribute. classList handles all of this for you.

> None of the modifications done through the dataset api would reflect in the DOM and be readable by CSS unless you were to convert the list to a space separated string and explicitly set the attribute. I'm really not sure what you mean by this. If you set the data attribute any of these ways, it can be targeted in CSS with [data-demo="example"]: el.dataset.demo = 'example' el.dataset['demo'] = 'example' el.setAttrib…

I'm just saying if you want to target something on an element it needs to be set in an attribute and classList takes care of this.

I use classes strictly for styling. I change these styles by adding and removing class names and classList handles it very well without me needing to read the data attribute, make it an array, manipulate it, join it and update the attribute.

Re: In defense of functional CSS

#243

Author here. In retrospect a couple months after writing this post, I don't love it. I still am in love with Tailwind and Functional CSS, but I did a poor job defending it. I'd suggest that everyone read this post [1] by Adam Wathan, the creator of Tailwind CSS. It does a much better job explaining and defending than I did. [1] https://adamwathan.me/css-utility-classes-and-separation-of-...

This is a great article, it helped clarify my understanding of functional CSS and made some really good points.

However, I still don't think it is the complete answer. Mostly, if I'm wearing my developer hat (rather than designer hat), functional CSS would drive me batty. If you are working in a larger team, where some of the team write the HTML and some write the CSS styling, this really disadvantages the people who work with the HTML. As a developer, I need to write HTML where I am semantically describing what the component is doing as I have no idea about the details of the design.

What might work is a hybrid approach? That is, designers work with functional CSS and then at the end, map the compositions back to the semantic class styling? I.e you would do mostly the same thing, but would move the functional CSS styling into the CSS and have a mappings at the end. Would this give the best of both worlds - keeping the HTML semantic, but still allowing designers to mostly work with functional CSS?

Re: In defense of functional CSS

#244
post #241

Earlier quoted context omitted.

> None of the modifications done through the dataset api would reflect in the DOM and be readable by CSS unless you were to convert the list to a space separated string and explicitly set the attribute. I'm really not sure what you mean by this. If you set the data attribute any of these ways, it can be targeted in CSS with [data-demo="example"]: el.dataset.demo = 'example' el.dataset['demo'] = 'example' el.setAttrib…

I'm just saying if you want to target something on an element it needs to be set in an attribute and classList takes care of this. I use classes strictly for styling. I change these styles by adding and removing class names and classList handles it very well without me needing to read the data attribute, make it an array, manipulate it, join it and update the attribute.

I feel like you're still thinking small in terms of attributes, and big in terms of values. Many many values all crammed into one attribute (class), but the reality is you can invent infinite (∞) data attributes. There's literally no need for you to format the values as a list of space-separated values…unless you want to. But if you don't want to, there's no need. Consider this, instead of targeting something with classes like this .active.demo, and setting it like this

    el.classList.add('active')
    el.classList.add('demo')
You would NOT need to do something like this to use data attributes, [data-example~=active][data-example~=demo] and to set it like this:

    if (!el.dataset.example.split(' ').includes('demo')) {
      el.dataset.example += ' demo'
    }
You could instead easily set two attributes and test for their presence, even if they don't have values (or you're not using them)

    el.dataset.active = el.dataset.demo = true
And then you can target that in CSS with [data-active][data-demo]. To remove them later is just as simple:

    el.dataset.active = false
And it's gone! Try to think BIG in terms of attributes, and small in terms of values. It's a lot nicer than trying to cram all of your values into just one attribute when you literally have infinite attributes available to work with!

Not only do you have infinite attributes to work with, but you can

Using classes as your only way to target styles, and ignoring the other aspects of how CSS selectors can target elements is like picking up a guitar and trying to play a song, but only plucking one string. You might be making it harder on yourself to get the job done, and the result isn't any better for the effort.

EDIT: Just for kicks, have you ever considered the flexibility of what data types you can set as an attribute value other than a space separated list of strings? Try this:

    // set JSON to attribute value
    document.documentElement.dataset.example = JSON.stringify({one: 1, two: 2})

    // get JSON from attribute value
    JSON.parse(document.documentElement.dataset.example)
You can even stick a bit of JSON there as the attribute value, which can be parse/stringified by JS, is _easy_ to add or remove properties from and work with on the JS side (not requiring helper methods like classList), and is _still_ targetable by CSS once set on an element :D The possibilities are endless, the apparent limitations a lot of people butt up against are self-imposed.

Re: In defense of functional CSS

#245
post #244

Earlier quoted context omitted.

I'm just saying if you want to target something on an element it needs to be set in an attribute and classList takes care of this. I use classes strictly for styling. I change these styles by adding and removing class names and classList handles it very well without me needing to read the data attribute, make it an array, manipulate it, join it and update the attribute.

I feel like you're still thinking small in terms of attributes, and big in terms of values. Many many values all crammed into one attribute (class), but the reality is you can invent infinite (∞) data attributes. There's literally no need for you to format the values as a list of space-separated values…unless you want to. But if you don't want to, there's no need. Consider this, instead of targeting something with cl…

I'm sorry I'm just not seeing the value in it. I'm just seeing more complexity JS and CSS wise without solving any problems.

Re: In defense of functional CSS

#246

This is really bad advice. You reduce errors by reducing code by wrapping your code in functions, thats functional and its how classes work. This article suggests the opposite just write everything from scratch perfectly, not going to happen. > there's nothing stopping you from continuing to add those semantic classes, even if they're irrelevant for styling If they are irrelevant to style then it could be applied to…

I tried this at one company. I have never gone back. It's terrible advice? You can only reconcile this as a matter of experience.

> You can only reconcile this as a matter of experience.

I was able to give three common and specific reasons why its bad advice, none of them where to just trust me, or my experience.

If the only reason you like something is because you like it, fair enough, good for you, you like a thing. Its ok to like things, but that doesn't mean there is any solid logic backing the things you like.

Post reply on HN