alexander
alexander

Reputation: 559

How to add a class to an element with CSS

CSS was introduced to separate the content of a website from it's presentation. I'm a proponent of a strict separation of concerns. The CSS class selector is very usefull to group HTML elements that don't have their own tag (e.g. class: "contact info card" if your page shows many cards). This is a good solution as long as the class selector is also relevant to someone with a text-only browser (to replace missing content tags). But as soon as you start adding class selectors to elements, that have nothing but the desired design-properties in common, you change the presentation from within the content (e.g. class: "background-black" is like using HTML-styling tags).

To keep a strict separation but still be able to reuse CSS code, I came up with this solution: Add a class to a HTML element where it makes sense from a content-point-of-view. If two or more elements that have nothing in common need to use the same complex CSS properties, each of them gets an id selector. Within the CSS file I would like to assign the complex-css-properties-class to the element for each id. How can I add a class to an id-selected element from within the CSS code? Do you know other ways to keep a strict separation of content and presentation?

Upvotes: 3

Views: 7435

Answers (3)

Josef Engelfrost
Josef Engelfrost

Reputation: 2965

For less complex structures, writing your CSS in a smart way might be enough:

/* Cards */
.employee, 
.service {
  font-size: 1.2em; 
  padding: 20px;
  margin: 20px;
  box-shadow: 0 0 .25rem #ccc;
}

.employee {
  color: blue;
  ...
}
.service {
  color: red;
  ...
}
<div>
  <div class="employee">Kim</div>
  <div class="employee">Jim</div>
</div>
<div>
  <div class="service">Ironing</div>  
  <div class="service">Washing up</div>
</div>

For the example above this may be fine, but for larger projects you might want a CSS pre-processor like Sass to keep it maintainable:

@mixin card() {
  font-size: 1.2em; 
  padding: 20px; 
  margin: 20px;
  box-shadow: 0 0 .25rem #ccc;
}

.employee {
  @include card();
  color: blue;
  ...
}

.service {
  @include card();
  color: red;
  ...
}

Edit 2015-11-27 Regarding separation of concerns I revisited Harry Roberts' CSS Guidelines today, and I think he explains a good interpretation of that regarding HTML and CSS. I thought I might post it because it is quite different from the interpretation in the question:

The separation of concerns when applied to front-end code is not about classes-in-HTML-purely-for-styling-hooks-blurring-the-lines-between-concerns; it is about the very fact that we are using different languages for markup and styling at all.

In short: having classes in your markup does not violate the separation of concerns. Classes merely act as an API to link two separate concerns together. The simplest way to separate concerns is to write well formed HTML and well formed CSS, and link to two together with sensible, judicious use of classes.

Upvotes: 1

Erick Petrucelli
Erick Petrucelli

Reputation: 14932

The short answer is: you can't.

Think about an HTML element as an object with many attributes. The class is one of those attributes, which can be changed only in the HTML itself or with JavaScript, since all element attributes are exposed by the Document Object Model. In the other hand, CSS has no access to HTML attributes.

In fact, it's already possible to read HTML data-* attributes and use that with content: attr(data-something) in the CSS. In the future maybe we'll be able to use attr() on any other CSS property. But even with it, no way to change an HTML attribute using only CSS.

So, if you really want something like you described, use JavaScript, searching the desired elements by id, then change the class as you want.

Upvotes: 0

David P
David P

Reputation: 2103

If you don't mind limiting your support to Web Components browsers, I suppose you could create your own custom tags, and then apply default css for each.

Upvotes: 0

Related Questions