HTML – CSS-Tricks https://css-tricks.com Tips, Tricks, and Techniques on using Cascading Style Sheets. Sat, 30 Mar 2024 02:12:36 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.3 https://i0.wp.com/css-tricks.com/wp-content/uploads/2021/07/star.png?fit=32%2C32&ssl=1 HTML – CSS-Tricks https://css-tricks.com 32 32 45537868 Accessible Forms with Pseudo Classes https://css-tricks.com/accessible-forms-with-pseudo-classes/ https://css-tricks.com/accessible-forms-with-pseudo-classes/#comments Fri, 22 Mar 2024 18:52:31 +0000 https://css-tricks.com/?p=377565 Hey all you wonderful developers out there! In this post, I am going to take you through creating a simple contact form using semantic HTML and an awesome CSS pseudo class known as :focus-within. The :focus-within class allows for …


Accessible Forms with Pseudo Classes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Hey all you wonderful developers out there! In this post, I am going to take you through creating a simple contact form using semantic HTML and an awesome CSS pseudo class known as :focus-within. The :focus-within class allows for great control over focus and letting your user know this is exactly where they are in the experience. Before we jump in, let’s get to the core of what web accessibility is.


Form Accessibility?


You have most likely heard the term “accessibility” everywhere or the numeronym, a11y. What does it mean? That is a great question with so many answers. When we look at the physical world, accessibility means things like having sharps containers in your bathrooms at your business, making sure there are ramps for wheel assisted people, and having peripherals like large print keyboards on hand for anyone that needs it.

The gamut of accessibility doesn’t stop there, we have digital accessibility that we need to be cognizant of as well, not just for external users, but internal colleagues as well. Color contrast is a low hanging fruit that we should be able to nip in the bud. At our workplaces, making sure that if any employee needs assistive tech like a screen reader, we have that installed and available. There are a lot of things that need to be kept into consideration. This article will focus on web accessibility by keeping the WCAG (web content accessibility guidelines) in mind.

MDN (Mozilla Developer Network)

The :focus-within CSS pseudo-class matches an element if the element or any of its descendants are focused. In other words, it represents an element that is itself matched by the :focus pseudo-class or has a descendant that is matched by :focus. (This includes descendants in shadow trees.)

This pseudo class is really great when you want to emphasize that the user is in fact interacting with the element. You can change the background color of the whole form, for example. Or, if focus is moved into an input, you can make the label bold and larger of an input element when focus is moved into that input. What is happening below in the code snippets and examples is what is making the form accessible. :focus-within is just one way we can use CSS to our advantage.

How To Focus


Focus, in regards to accessibility and the web experience, is the visual indicator that something is being interacted with on the page, in the UI, or within a component. CSS can tell when an interactive element is focused.

“The :focus CSS pseudo-class represents an element (such as a form input) that has received focus. It is generally triggered when the user clicks or taps on an element or selects it with the keyboard’s Tab key.”

MDN (Mozilla Developer Network)

Always make sure that the focus indicator or the ring around focusable elements maintains the proper color contrast through the experience.

Focus is written like this and can be styled to match your branding if you choose to style it.

:focus {
  * / INSERT STYLES HERE /*
}

Whatever you do, never set your outline to 0 or none. Doing so will remove a visible focus indicator for everyone across the whole experience. If you need to remove focus, you can, but make sure to add that back in later. When you remove focus from your CSS or set the outline to 0 or none, it removes the focus ring for all your users. This is seen a lot when using a CSS reset. A CSS reset will reset the styles to a blank canvas. This way you are in charge of the empty canvas to style as you wish. If you wish to use a CSS reset, check out Josh Comeau’s reset.

*DO NOT DO what is below!

:focus {
  outline: 0;
}

:focus {
  outline: none;
}


Look Within!


One of the coolest ways to style focus using CSS is what this article is all about. If you haven’t checked out the :focus-within pseudo class, definitely give that a look! There are a lot of hidden gems when it comes to using semantic markup and CSS, and this is one of them. A lot of things that are overlooked are accessible by default, for instance, semantic markup is by default accessible and should be used over div’s at all times.

<header>
  <h1>Semantic Markup</h1>
  <nav>
    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="/about">About</a></li>
    </ul>
  </nav>
</header>

<section><!-- Code goes here --></section>

<section><!-- Code goes here --></section>

<aside><!-- Code goes here --></aside>

<footer><!-- Code goes here --></footer>

The header, nav, main, section, aside, and footer are all semantic elements. The h1 and ul are also semantic and accessible.

Unless there is a custom component that needs to be created, then a div is fine to use, paired with ARIA (Accessible Rich Internet Applications). We can do a deep dive into ARIA in a later post. For now let’s focus…see what I did there…on this CSS pseudo class.

The :focus-within pseudo class allows you to select an element when any descendent element it contains has focus.


:focus-within in Action!

HTML

<form>
  <div>
    <label for="firstName">First Name</label><input id="firstName" type="text">
  </div>
  <div>
    <label for="lastName">Last Name</label><input id="lastName" type="text">
  </div>
  <div>
    <label for="phone">Phone Number</label><input id="phone" type="text">
  </div>
  <div>
    <label for="message">Message</label><textarea id="message"></textarea>
  </div>
</form>

CSS

form:focus-within {
  background: #ff7300;
  color: black;
  padding: 10px;
}

The example code above will add a background color of orange, add some padding, and change the color of the labels to black.

The final product looks something like below. Of course the possibilities are endless to change up the styling, but this should get you on a good track to make the web more accessible for everyone!

First example of focus-within css class highlighting the form background and changing the label text color.

Another use case for using :focus-within would be turning the labels bold, a different color, or enlarging them for users with low vision. The example code for that would look something like below.

HTML

<form>
  <h1>:focus-within part 2!</h1>
  <label for="firstName">First Name: <input name="firstName" type="text" /></label>
  <label for="lastName">Last Name: <input name="lastName" type="text" /></label>
  <label for="phone">Phone number: <input type="tel" id="phone" /></label>
  <label for="message">Message: <textarea name="message" id="message"/></textarea></label>
</form>

CSS

label {
  display: block;
  margin-right: 10px;
  padding-bottom: 15px;
}

label:focus-within {
  font-weight: bold;
  color: red;
  font-size: 1.6em;
}
Showing how to bold, change color and font size of labels in a form using :focus-within.

:focus-within also has great browser support across the board according to Can I use.

Focus within css pseudo class browser support according to the can i use website.

Conclusion

Creating amazing, accessible user experience should always be a top priority when shipping software, not just externally but internally as well. We as developers, all the way up to senior leadership need to be cognizant of the challenges others face and how we can be ambassadors for the web platform to make it a better place.

Using technology like semantic markup and CSS to create inclusive spaces is a crucial part in making the web a better place, let’s continue moving forward and changing lives.

Check out another great resource here on CSS-Tricks on using :focus-within.


Accessible Forms with Pseudo Classes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/accessible-forms-with-pseudo-classes/feed/ 12 377565
Roundup of Recent Document Outline Chatter https://css-tricks.com/roundup-of-recent-document-outline-chatter/ https://css-tricks.com/roundup-of-recent-document-outline-chatter/#comments Thu, 21 Jul 2022 14:04:34 +0000 https://css-tricks.com/?p=367048 It’s not everyday that HTML headings are the topic de jour, but my folder of saved links is accumulating articles about the recently merged removal of the document outline algorithm in the WHATWG Living Standard.

First off, you should know …


Roundup of Recent Document Outline Chatter originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
It’s not everyday that HTML headings are the topic de jour, but my folder of saved links is accumulating articles about the recently merged removal of the document outline algorithm in the WHATWG Living Standard.

First off, you should know that the algorithm never really existed. Sure, it was in the spec. And sure, there was a warning about using it in the spec. But no browser ever implemented it, as Bruce Lawson reminded us. We have been living in a flat document structure the whole time.

This is very old news. Adrian Roselli has been writing about the document outline myth since 2013. But it’s his 2016 post titled “There Is No Document Outline Algorithm” that comprehensively spells it out and has been updated regularly with extra nuggets of context about the conversations and struggles that got us here. This is really the best timeline of the saga. Amelia Bellamy-Royds has also delved into the roots of the dilemma in the past here on CSS-Tricks.

My mind instantly goes to all the work that’s gone into the making of a document outline algorithm that supports sectioning. Removing it from the spec is the right call for sure, but it doesn’t take away from the herculean efforts that went into it even if it is now buried in some version history. I also think about all the well-intentioned folks who have written about the algorithm erroneously over time (including on this very site!) with the expectation that it was just around the corner. There’s nearly seven years of mental and technical debt that we’ve accrued from what appear to be a lack of action.

Looking past the “news” that the algorithm is officially no more, Bruce laments that there is no generic <h> element or the like that can be sectioned to produce the correct heading level. I agree. Having an <h1> element essentially exist as an exposed <title> is constraining, particularly since pages are so rarely structured around a single article with a single top-level heading. I often find myself wincing every time I’m making some sort of card component where using <h3> might be technically correct, but feels out of order. And that’s before we even talk about the styling considerations where a lower heading level now needs to look like a distinct higher heading level.

Speaking of heading level management, Steve Faulkner (who authored the PR that plucked the algorithm from the spec) has a super practical overview of using the <hgroup> element to handle heading patterns that involve subheadings, subtitles, alternative titles, snd taglines. I’m sure you’ve seen markup like this in the wild:

<h1>Disappointingly Average</h1>
<h2>The Autobiography of Geoff Graham</h2>
<h3>by Geoff Graham</h3>

That doesn’t jive with a flat document outline that’s driven by heading levels. Each one of those headings represents a section that forms a hierarchy of information:

Disappointingly Average
└── The Autobiography of Geoff Graham
    └── by Geoff Graham

What we want instead is a group of headings. Cue the <hgroup> element:

When nested within a <hgroup> element, the <p> element’s content represents a subheading, alternative title, or tagline which are not included in the document outline.

So, we get this structure:

<hgroup>
  <h1>Disappointingly Average</h1>
  <p>The Autobiography of Geoff Graham</p>
  <p>by Geoff Graham</p>
</hgroup>

<hgroup> is role=generic at the moment, but Steve points to a proposal that could map it to role=group. If that happens, the accessibility tree will allow assistive tech to assign more semantic meaning to those paragraphs as the subtitle and tagline pieces that they are. Sounds easy but Steve notes challenges that are in the way. He also demos how this sort of pattern could be implemented today with ARIA attributes.

As long as we’re rounding things up, Matthias Ott published a few tips on creating a structured outline with headings. Check out the end for a great list of tools to check your heading outlines.


Roundup of Recent Document Outline Chatter originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/roundup-of-recent-document-outline-chatter/feed/ 2 367048
Write HTML, the HTML Way (Not the XHTML Way) https://css-tricks.com/write-html-the-html-way-not-the-xhtml-way/ https://css-tricks.com/write-html-the-html-way-not-the-xhtml-way/#comments Mon, 21 Mar 2022 20:08:38 +0000 https://css-tricks.com/?p=363745 You may not use XHTML (anymore), but when you write HTML, you may be more influenced by XHTML than you think. You are very likely writing HTML, the XHTML way.

What is the XHTML way of writing HTML, and what …


Write HTML, the HTML Way (Not the XHTML Way) originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
You may not use XHTML (anymore), but when you write HTML, you may be more influenced by XHTML than you think. You are very likely writing HTML, the XHTML way.

What is the XHTML way of writing HTML, and what is the HTML way of writing HTML? Let’s have a look.

HTML, XHTML, HTML

In the 1990s, there was HTML. In the 2000s, there was XHTML. Then, in the 2010s, we switched back to HTML. That’s the simple story.

You can tell by the rough dates of the specifications, too: HTML “1” 1992, HTML 2.0 1995, HTML 3.2 1997, HTML 4.01 1999; XHTML 1.0 2000, XHTML 1.1 2001; “HTML5” 2007.

XHTML became popular when everyone believed XML and XML derivatives were the future. “XML all the things.” For HTML, this had a profound effect: The effect that we learned to write it the XHTML way.

The XHTML way of writing HTML

The XHTML way is well-documented, because XHTML 1.0 describes in great detail in its section on “Differences with HTML 4”:

  • Documents must be well-formed.
  • Element and attribute names must be in lower case.
  • For non-empty elements, end tags are required.
  • Attribute values must always be quoted.
  • Attribute minimization is not supported.
  • Empty elements need to be closed.
  • White space handling in attribute values is done according to XML.
  • Script and style elements need CDATA sections.
  • SGML exclusions are not possible.
  • The elements with id and name attributes, like a, applet, form, frame, iframe, img, and map, should only use id.
  • Attributes with pre-defined value sets are case-sensitive.
  • Entity references as hex values must be in lowercase.

Does this look familiar? With the exception of marking CDATA content, as well as dealing with SGML exclusions, you probably follow all of these rules. All of them.

Although XHTML is dead, many of these rules have never been questioned again. Some have even been elevated to “best practices” for HTML.

That is the XHTML way of writing HTML, and its lasting impact on the field.

The HTML way of writing HTML

One way of walking us back is to negate the rules imposed by XHTML. Let’s actually do this (without the SGML part, because HTML isn’t based on SGML anymore):

  • Documents may not be well-formed.
  • Element and attribute names may not be in lower case.
  • For non-empty elements, end tags are not always required.
  • Attribute values may not always be quoted.
  • Attribute minimization is supported.
  • Empty elements don’t need to be closed.
  • White space handling in attribute values isn’t done according to XML.
  • Script and style elements don’t need CDATA sections.
  • The elements with id and name attributes may not only use id.
  • Attributes with pre-defined value sets are not case-sensitive.
  • Entity references as hex values may not only be in lowercase.

Let’s remove the esoteric things; the things that don’t seem relevant. This includes XML whitespace handling, CDATA sections, doubling of name attribute values, the case of pre-defined value sets, and hexadecimal entity references:

  • Documents may not be well-formed.
  • Element and attribute names may not be in lowercase.
  • For non-empty elements, end tags are not always required.
  • Attribute values may not always be quoted.
  • Attribute minimization is supported.
  • Empty elements don’t need to be closed.

Peeling away from these rules, this looks a lot less like we’re working with XML, and more like working with HTML. But we’re not done yet.

“Documents may not be well-formed” suggests that it was fine if HTML code was invalid. It was fine for XHTML to point to wellformedness because of XML’s strict error handling. But while HTML documents work even when they contain severe syntax and wellformedness issues, it’s neither useful for the professional — nor our field — to use and abuse this resilience. (I’ve argued this case before in my article, “In Critical Defense of Frontend Development.”)

The HTML way would therefore not suggest “documents may not be well-formed.” It would also be clear that not only end, but also start tags aren’t always required. Rephrasing and reordering, this is the essence:

  • Start and end tags are not always required.
  • Empty elements don’t need to be closed.
  • Element and attribute names may be lower or upper case.
  • Attribute values may not always be quoted.
  • Attribute minimization is supported.

Examples

How does this look like in practice? For start and end tags, be aware that many tags are optional. A paragraph and a list, for example, are written like this in XHTML:

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<ul>
  <li>Praesent augue nisl</li>
  <li>Lobortis nec bibendum ut</li>
  <li>Dictum ac quam</li>
</ul>

In HTML, however, you can write them using only this code (which is valid):

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<ul>
  <li>Praesent augue nisl
  <li>Lobortis nec bibendum ut
  <li>Dictum ac quam
</ul>

Developers also learned to write void elements, like so:

<br />

This is something XHTML brought to HTML, but as the slash has no effect on void elements, you only need this:

<br>

In HTML, you can also just write everything in all caps:

<A HREF="https://css-tricks.com/">CSS-Tricks</A>

It looks like you’re yelling and you may not like it, but it’s okay to write it like this.

When you want to condense that link, HTML offers you the option to leave out certain quotes:

<A HREF=https://css-tricks.com/>CSS-Tricks</A>

As a rule of thumb, when the attribute value doesn’t contain a space or an equal sign, it’s usually fine to drop the quotes.

Finally, HTML–HTML — not XHTML–HTML — also allows to minimize attributes. That is, instead of marking an input element as required and read-only, like this:

<input type="text" required="required" readonly="readonly">

You can minimize the attributes:

<input type="text" required readonly>

If you’re not only taking advantage of the fact that the quotes aren’t needed, but that text is the default for the type attribute here (there are more such unneeded attribute–value combinations), you get an example that shows HTML in all its minimal beauty:

<input required readonly>

Write HTML, the HTML way

The above isn’t a representation of where HTML was in the 90s. HTML, back then, was loaded with <table> elements for layout, packed with presentational code, largely invalid (as it’s still today), with wildly varying user agent support. Yet it’s the essence of what we would have wanted to keep if XML and XHTML hadn’t come around.

If you’re open to a suggestion of what a more comprehensive, contemporary way of writing HTML could look like, I have one. (HTML is my main focus area, so I’m augmenting this by links to some of my articles.)

  1. Respect syntax and semantics.
  2. Use the options HTML gives you, as long as you do so consistently.
    • Remember that element and attribute names may be lowercase or uppercase.
  3. Keep use of HTML to the absolute minimum
    • Remember that presentational and behavioral markup is to be handled by CSS and JavaScript instead.
    • Remember that start and end tags are not always required.
    • Remember that empty elements don’t need to be closed.
    • Remember that some attributes have defaults that allow these attribute–value pairs to be omitted.
    • Remember that attribute values may not always be quoted.
    • Remember that attribute minimization is supported.

It’s not a coincidence that this resembles the three ground rules for HTML, that it works with the premise of a smaller payload also leading to faster sites, and that this follows the school of minimal web development. None of this is new — our field could merely decide to rediscover it. Tooling is available, too: html-minifier is probably the most established and able to handle all HTML optimizations.

You’ve learned HTML the XHTML way. HTML isn’t XHTML. Rediscover HTML, and help shape a new, modern way of writing HTML — which acknowledges, but isn’t necessarily based on XML.


Write HTML, the HTML Way (Not the XHTML Way) originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/write-html-the-html-way-not-the-xhtml-way/feed/ 41 363745
HTML Sanitizer API https://css-tricks.com/html-sanitizer-api/ https://css-tricks.com/html-sanitizer-api/#comments Thu, 16 Dec 2021 18:21:31 +0000 https://css-tricks.com/?p=359306 Three cheers for (draft stage) progress on a Sanitizer API! It’s gospel that you can’t trust user input. And indeed, any app I’ve ever worked on has dealt with bad actors trying to slip in and execute nefarious code …


HTML Sanitizer API originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Three cheers for (draft stage) progress on a Sanitizer API! It’s gospel that you can’t trust user input. And indeed, any app I’ve ever worked on has dealt with bad actors trying to slip in and execute nefarious code somewhere it shouldn’t.

It’s the web developer’s job to clean user input before it is used again on the page (or stored, or used server-side). This is typically done with our own code or libraries that are pulled down to help. We might write a RegEx to strip anything that looks like HTML (or the like), which has the risk of bugs and those bad actors finding a way around what our code is doing.

Instead of user-land libraries or our dancing with it ourselves, we could let the browser do it:

// some function that turns a string into real nodes
const untrusted_input = to_node("<em onclick='alert(1);'>Hello!</em>");

const sanitizer = new Sanitizer();
sanitizer.sanitize(untrusted_input);  // <em>Hello!</em>

Then let it continue to be a browser responsibility over time. As the draft report says:

The browser has a fairly good idea of when it is going to execute code. We can improve upon the user-space libraries by teaching the browser how to render HTML from an arbitrary string in a safe manner, and do so in a way that is much more likely to be maintained and updated along with the browser’s own changing parser implementation.

This kind of thing is web standards at its best. Spot something annoying (and/or dangerous) that tons of people have to do, and step in to make it safer, faster, and better.

To Shared LinkPermalink on CSS-Tricks


HTML Sanitizer API originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/html-sanitizer-api/feed/ 6 359306
Semantic menu context https://css-tricks.com/semantic-menu-context/ https://css-tricks.com/semantic-menu-context/#comments Thu, 11 Nov 2021 20:07:40 +0000 https://css-tricks.com/?p=356652 Scott digs into the history of the <menu> element. He traced it as far back as HTML 2 (!) in a 1994 changelog. The vibe then, it seems, was to mark up a list. I would suspect the intention …


Semantic menu context originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Scott digs into the history of the <menu> element. He traced it as far back as HTML 2 (!) in a 1994 changelog. The vibe then, it seems, was to mark up a list. I would suspect the intention is much like <nav> is today, but I really don’t know.

Short story: HTML 4 deprecated it, HTML 5 revived it—this time as a “group of commands”—and then HTML 5.2 deprecated it again. Kind of a bummer since it has some clear use cases.

So, it’s been quite the roller coaster for ol’ <menu>! There never seems to be any easy wins for HTML evolution. As of now, it’s in “don’t bother” territory:

I really wrote this post as a sort of counter point to the often uttered phrase “use semantic HTML and you get accessibility for free!” That statement, on its surface, is largely true. And you should use semantic HTML wherever its use is appropriate. <menu>, unfortunately, doesn’t really give us all that much, even though it has clearly defined semantics. Its intended semantics and what we actually need in reality are better served by either just using the more robust <ul> element, or creating your own role=toolbarmenubar, etc.. Using this semantic element, for semantics sake, is just that.

To Shared LinkPermalink on CSS-Tricks


Semantic menu context originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/semantic-menu-context/feed/ 3 356652
Jekyll doesn’t do components? Liar! https://css-tricks.com/jekyll-doesnt-do-components-liar/ https://css-tricks.com/jekyll-doesnt-do-components-liar/#comments Fri, 08 Oct 2021 17:14:05 +0000 https://css-tricks.com/?p=353374 I like the pushback from Katie Kodes here. I’ve said in the past that I don’t think server-side languages haven’t quite nailed “building in components” as well as JavaScript has, but hey, this is a good point:

1. Any basic


Jekyll doesn’t do components? Liar! originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
I like the pushback from Katie Kodes here. I’ve said in the past that I don’t think server-side languages haven’t quite nailed “building in components” as well as JavaScript has, but hey, this is a good point:

1. Any basic fragment-of-HTML “component” you can define with JSX in a file and then cross-reference as <MyComponent key="value" />, you can just as easily define with Liquid in a file and cross-reference in Jekyll as {% include MyComponent.html key=value %}.

2. Any basic fragment-of-HTML “layout” you can define with JSX in a file and then cross-reference as <MyLayout>Hello, world</MyLayout>, you can just as easily define with Liquid in a file and then cross-reference in the front matter of a Jekyll template as layout: MyLayout.

Any HTML preprocessor that can do partials with local variables is pretty close to replicating the best of stateless JavaScript components. The line gets even blurrier with stuff like Eleventy Serverless that can build individual pages on the fly by hitting the URL of a cloud function.

To Shared LinkPermalink on CSS-Tricks


Jekyll doesn’t do components? Liar! originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/jekyll-doesnt-do-components-liar/feed/ 2 353374
Tabs in HTML? https://css-tricks.com/tabs-in-html/ https://css-tricks.com/tabs-in-html/#respond Mon, 16 Aug 2021 23:31:01 +0000 https://css-tricks.com/?p=346418 Brian Kardell shares a bit about the progress of bringing "Tabs" to HTML. We kinda think we know what they are, but you have to be really specific when dealing with specs and defining them. It's tricky.


Tabs in HTML? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
You know what tabs are, Brian.

I mean… You use them every day, on every OS. Everybody knows they exist in every toolbox. All that’s left is to “just pave the cowpaths!” But when you get right down to it, it’s a lot more complicated than that.

Brian Kardell shares a bit about the progress of bringing “Tabs” to HTML. We kinda think we know what they are, but you have to be really specific when dealing with specs and defining them. It’s tricky. Then, even if you settle on a solid definition, an HTML expression of that isn’t exactly clear. There are all kinds of expressions of tabs that all make sense in their own way. Imagine marking up tabs where you put all the tabs as a row of links or buttons up top, and then a bunch of panels below that. They call that a “Table of Contents” style of markup, and it makes some kind of logical sense (“the markup looks like tabs already”). But it also has some problems, and it looks like sections-with-headers is more practical (“If you have the heading, you can build the TOC, but not vice-versa”). Spicy sections are a totally different pattern. And that’s just one problem they are facing.

I don’t envy the work, but I look forward to the progress in no small part because authoring tabs is tricky business. Not hard to do, but very hard to do right. I’ve talked in the past about how I’ve built tabs many times in jQuery where just a click handler on a row of links hides or shows some matching divs below. That “works” if you ignore accessibility entirely (e.g. how you navigate between tabs, focus management, ARIA expectations, etc).

Here’s the ShopTalk discussion and here’s a different perspective in a chat I had with Stephen on CodePen Radio where we get into our <Tabs /> React component on CodePen.

To Shared LinkPermalink on CSS-Tricks


Tabs in HTML? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/tabs-in-html/feed/ 0 346418
HTML is Not a Programming Language? https://css-tricks.com/html-is-not-a-programming-language/ https://css-tricks.com/html-is-not-a-programming-language/#comments Mon, 16 Aug 2021 14:44:35 +0000 https://css-tricks.com/?p=346318

HTML is not a programming language.

I’ve heard that sentence so many times and it’s tiring. Normally, it is followed by something like, It doesn’t have logic, or, It is not Turing complete,.so… obviously it is not a programming …


HTML is Not a Programming Language? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>

HTML is not a programming language.

I’ve heard that sentence so many times and it’s tiring. Normally, it is followed by something like, It doesn’t have logic, or, It is not Turing complete,.so… obviously it is not a programming language. Like it’s case-closed and should be the end of the conversation.

Should it be, though?

I want to look at typical arguments I hear used to belittle HTML and offer my own rebuttals to show how those claims are not completely correct.

My goal is not to prove that HTML is or is not a programming language, but to show that the three main arguments used for claiming it is not are flawed or incorrect, thus invalidating the conclusion from a logical point of view.

“HTML is a markup language, not a programming language”

This statement, by itself, sounds great… but it is wrong: markup languages can be programming languages. Not all of them are (most are not) but they can be. If we drew a Venn diagram of programming languages and markup languages, it would not be two separate circles, but two circles that slightly intersect:

A markup language that operates with variables, has control structures, loops, etc., would also be a programming language. They are not mutually exclusive concepts.

TeX and LaTeX are examples of markup languages that are also considered programming languages. It may not be practical to develop with them, but it is possible. And we can find examples online, like a BASIC interpreter or a Mars Rover controller (which won the Judges’ prize in the ICFP 2008 programming contest).

While some markup languages might be considered programming languages, I’m not saying that HTML is one of them. The point is that the original statement is wrong: markup languages can be programming languages. Therefore, saying that HTML is not a programming language because it is a markup language is based on a false statement, and whatever conclusion you arrive at from that premise will be categorically wrong.

“HTML doesn’t have logic”

This claim demands that we clarify what “logic” means because the definition might just surprise you.

As with Turing-completeness (which we’ll definitely get to), those who bring this argument to the table seem to misunderstand what it is exactly. I’ve asked people to tell me what they mean by “logic” and have gotten interesting answers back like:

Logic is a sensible reason or way of thinking.

That’s nice if what we’re looking for is a dictionary definition of logic. But we are talking about programming logic, not just logic as a general term. I’ve also received answers like:

Programming languages have variables, conditions, loops, etc. HTML is not a programming language because you can’t use variables or conditions. It has no logic.

This is fine (and definitely better than getting into true/false/AND/OR/etc.), but also incorrect. HTML does have variables — in the form of attributes — and there are control structures that can be used along with those variables/attributes to determine what is displayed.

But how do you control those variables? You need JavaScript!

Wrong again. There are some HTML elements that have internal control logic and don’t require JavaScript or CSS to work. And I’m not talking about things like <link> or <noscript> – which are rudimentary control structures and have been part of the standard for decades. I’m referring to elements that will respond to the user input and perform conditional actions depending on the current state of the element and the value of a variable. Take the <details>/<summary> tuple or the <dialog> element as examples: when a user clicks on them, they will close if the open attribute is present, and they will open if it is not. No JavaScript required.

So just saying alone that HTML isn’t a programming language because it lacks logic is misleading. We know that HTML is indeed capable of making decisions based on user input. HTML has logic, but it is inherently different from the logic of other languages that are designed to manipulate data. We’re going to need a stronger argument than that to prove that HTML isn’t a form of programming.

“HTML is not ‘Turing complete’”

OK, this is the one we see most often in this debate. It’s technically correct (the best kind of correct) to say HTML is not Turing complete, but it should spark a bigger debate than just using it as a case-closing statement.

I’m not going to get into the weeds on what it means to be Turing complete because there are plenty of resources on the topic. In fact, Lara Schenck summarizes it nicely in a post where she argues that CSS is Turing complete:

In the simplest terms, for a language or machine to be Turing complete, it means that it is capable of doing what a Turing machine could do: perform any calculation, a.k.a. universal computation. After all, programming was invented to do math although we do a lot more with it now, of course!

Because most modern programming languages are Turing complete, people use that as the definition of a programming language. But Turing-completeness is not that. It is a criterion to identify if a system (or its ruleset) can simulate a Turing machine. It can be used to classify programming languages; it doesn’t define them. It doesn’t even apply exclusively to programming languages. Take, for example, the game Minecraft (which meets that criterion) or the card game Magic: The Gathering (which also meets the criterion). Both are Turing complete but I doubt anyone would classify them as programming languages.

Turing-completeness is fashionable right now the same way that some in the past considered the difference between compiled vs. interpreted languages to be good criteria. Yes. We don’t have to make a big memory effort to remember when developers (mainly back-end) downplayed front-end programming (including JavaScript and PHP) as not “real programming.” You still hear it sometimes, although now faded, mumbled, and muttered.

The definition of what programming is (or is not) changes with time. I bet someone sorting through punched cards complained about how typing code in assembly was not real programming. There’s nothing universal or written in stone. There’s no actual definition.

Turing-completeness is a fair standard, I must say, but one that is biased and subjective — not in its form but in the way it is picked. Why is it that a language capable of generating a Turing Complete Machine gets riveted as a “programming language” while another capable of generating a Finite State Machine is not? It is subjective. It is an excuse like any other to differentiate between “real developers” (the ones making the claim) and those inferior to them.

To add insult to injury, it is obvious that many of the people parroting the “HTML is not Turing complete” mantra don’t even know or understand what Turing-completeness means. It is not an award or a seal of quality. It is not a badge of honor. It is just a way to categorize programming languages — to group them, not define them. A programming language could be Turing complete or not in the same way that it could be interpreted or compiled, imperative or declarative, procedural or object-oriented.


So, is HTML a programming language?

If we can debase the main arguments claiming that HTML is not a programming language, does that actually mean that HTML is a programming language? No, it doesn’t. And so, the debate will live on until the HTML standard evolves or the “current definition” of programming language changes.

But as developers, we must be wary of this question as, in many cases, it is not used to spark a serious debate but to stir controversy while hiding ulterior motives: from getting easy Internet reactions, to dangerously diminishing the contribution of a group of people to the development ecosystem.

Or, as Ashley Kolodziej beautifully sums it up in her ode to HTML:

They say you’re not a real programming language like the others, that you’re just markup, and technically speaking, I suppose that’s right. Technically speaking, JavaScript and PHP are scripting languages. I remember when it wasn’t cool to know JavaScript, when it wasn’t a “real” language too. Sometimes, I feel like these distinctions are meaningless, like we built a vocabulary to hold you (and by extension, ourselves as developers) back. You, as a markup language, have your own unique value and strengths. Knowing how to work with you best is a true expertise, one that is too often overlooked.

Independent of the stance that we take on the “HTML is/isn’t a programming language” discussion, let’s celebrate it and not deny its importance: HTML is the backbone of the Internet. It’s a beautiful language with vast documentation and extensive syntax, yet so simple that it can be learned in an afternoon, and so complex that it takes years to master. Programming language or not, what really matters is that we have HTML in the first place.


HTML is Not a Programming Language? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/html-is-not-a-programming-language/feed/ 42 346318
Zero-Width Space https://css-tricks.com/zero-width-space/ https://css-tricks.com/zero-width-space/#comments Fri, 02 Jul 2021 20:39:04 +0000 https://css-tricks.com/?p=343435 The name zero-width space is antithetical, but it’s not without uses. In text, maybe you’d use it around slashes because you want to be sure the words are treated individually but not have any physical space around the slash:…


Zero-Width Space originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
The name zero-width space is antithetical, but it’s not without uses. In text, maybe you’d use it around slashes because you want to be sure the words are treated individually but not have any physical space around the slash:

That’s an image. WordPress was being weird about it and not escaping it even when in a code block.

That’s pretty theoretical though—I’ve never once needed to do that. It might be useful in a long word to suggest that it can be broken there… but that’s also rare as we have the soft-hyphen (&shy;) which is designed for that and leaves a typically appropriate hyphen at the break.

What I have needed to do is exactly the opposite: trick a system into thinking a single word is two words. Like on Twitter, if I @username or #hashtag in the text of a tweet, those will be linked up respectively. But I don’t always want that. On CSS Twitter, I might want to refer to a @media query or show an #id-selector. Toss a zero-width space between the symbols and the text and I’m all set.

Get a zero-width space on your clipboard

Here’s a Pen I created ages ago that will help you do that:

There is also a quick trick for doing it from the browser console:

copy('u{200B}')

via:

https://twitter.com/markdalgleish/status/1338323521647169536

And for yet another way that may appeal to you, a bookmarklet!

Copy & Paste concern

The danger with the zero-width space is, well, you can’t see it. If someone were to, for example, copy your @media query using the zero-width space trick from a tweet, it won’t work in their code editor (because it will invalidate the rule) and it might be extremely confusing. For that reason, it’s probably good to avoid using it in anything that might be copied as a code example, but probably fine when explicitly trying to not autolink something.


Zero-Width Space originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/zero-width-space/feed/ 22 343435
HTML Boilerplates https://css-tricks.com/html-boilerplates/ https://css-tricks.com/html-boilerplates/#comments Fri, 14 May 2021 14:13:07 +0000 https://css-tricks.com/?p=340403 Manuel Matuzović goes line-by-line through a boilerplate HTML document. I like it. It’s a good reference and has a lot of the same type of stuff I tend to put in the main HTML template. It makes me think about …


HTML Boilerplates originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Manuel Matuzović goes line-by-line through a boilerplate HTML document. I like it. It’s a good reference and has a lot of the same type of stuff I tend to put in the main HTML template. It makes me think about how opinionated this kind of thing can be. Dang near every line! Not the DOCTYPE, not the <title>, but nearly everything else.

The HTML
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width">

  <title>Unique page title - My Site</title>

  <script type="module">
    document.documentElement.classList.remove('no-js');
    document.documentElement.classList.add('js');
  </script>

  <link rel="stylesheet" href="/assets/css/styles.css">
  <link rel="stylesheet" href="/assets/css/print.css" media="print">

  <meta name="description" content="Page description">
  <meta property="og:title" content="Unique page title - My Site">
  <meta property="og:description" content="Page description">
  <meta property="og:image" content="https://www.mywebsite.com/image.jpg">
  <meta property="og:image:alt" content="Image description">
  <meta property="og:locale" content="en_GB">
  <meta property="og:type" content="website">
  <meta name="twitter:card" content="summary_large_image">
  <meta property="og:url" content="https://www.mywebsite.com/page">
  <link rel="canonical" href="https://www.mywebsite.com/page">

  <link rel="icon" href="/favicon.ico">
  <link rel="icon" href="/favicon.svg" type="image/svg+xml">
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">
  <link rel="manifest" href="/my.webmanifest">
  <meta name="theme-color" content="#FF00FF">
</head>

<body>
  <!-- Content -->
  <script src="/assets/js/xy-polyfill.js" nomodule></script>
  <script src="/assets/js/script.js" type="module"></script>
</body>
</html>

Maybe my site doesn’t use any JavaScript or have no-JavaScript fallbacks so I don’t need any of the class name dancing. Maybe my site doesn’t need print styles, but I do need link prefetching. Maybe I don’t care about social images, but I do want critical CSS in the head. It’s a boilerplate, not a prescription — it’s meant to be changed.

There was a time when HTML5 Boilerplate was a huge project in this space. It has a whole GitHub Org! The boilerplate has 50,000 stars! Personally, I feel like the project lost its way when it started to have a src and dist folder and a 200-line Gulp build process, ya know? It worked best as a reference for what stuff any given web project might need, but now I feel like it is intimidating in a way it doesn’t need to be. The boilerplate index file is also quite opinionated. It assumes Normalize and Modernizr, which are certainly not deprecated projects, but also not things I see developers reaching for much anymore. It even assumes Google Analytics usage!

I have no problem with people having and sharing boilerplate documents, but considering how unavoidable being opinionated it is with them, I also like the reference guide approach. Just show me every possible thing that can go in the <head> (a lot of the value of these boilerplates), and I’ll pick and choose what I need (or may have forgotten). To that end, Josh Buchea’s HEAD project is pretty cool.


HTML Boilerplates originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/html-boilerplates/feed/ 2 340403
The `ping` attribute on anchor links https://css-tricks.com/the-ping-attribute-on-anchor-links/ https://css-tricks.com/the-ping-attribute-on-anchor-links/#comments Thu, 08 Apr 2021 17:31:16 +0000 https://css-tricks.com/?p=337821 I didn’t know this was a thing until Stefan Judis’s post:

<a href="https://www.stefanjudis.com/popular-posts/" 
   ping="https://www.stefanjudis.com/tracking/"Read popular posts</a

You give an anchor link a URL via a ping attribute, and the browser will hit that URL with a web request …


The `ping` attribute on anchor links originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
I didn’t know this was a thing until Stefan Judis’s post:

<a href="https://www.stefanjudis.com/popular-posts/" 
   ping="https://www.stefanjudis.com/tracking/">Read popular posts</a>

You give an anchor link a URL via a ping attribute, and the browser will hit that URL with a web request (a literal PING) when clicked. The headers have a ping-to key with the href value of the link.

Why? Data. Wouldn’t it be nice to know what off-site links people are clicking on your website?

Even if you have Google Analytics installed, you don’t get that data by default. You’d have to write something custom or use something like their autotrack plugin with the outboundLinkTracker. Whatever you do, it is non-trivial, as in order to work, it has to:

  1. Have JavaScript intervene
  2. Prevent the default action of the link (going to the website)
  3. Track the event (send a ping somewhere)
  4. Then tell the browser to actually go to the website (window.location = …)

That’s because running a bit of JavaScript to ping your tracking service is unreliable on an off-site click. Your site is unloading and the new site loading as fast as possible, meaning that ping might not get a chance to run.

Presumably, with the ping attribute, you don’t have to do this little JavaScript dance of sending the ping before the page unloads — it will “just work.” That’s a big plus for this technique. It’s so cool to move complex ideas to lower-level languages that work easier and better.

There are heaps of downsides though. You don’t exactly get a nice API for sending along metadata. The best you could do is append a query string for extra data (e.g., was the link in the footer? or was it in a blog post?). But perhaps the biggest limitation is that it’s only for anchor links. If you were building a really serious event tracking thing, you’d want it to be useful for any type of event (not just clicks) on any type of element (not just links). So it’s not terribly surprising this is almost entirely the JavaScript’s domain.

To Shared LinkPermalink on CSS-Tricks


The `ping` attribute on anchor links originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/the-ping-attribute-on-anchor-links/feed/ 8 337821
Definition Tag https://css-tricks.com/definition-tag/ https://css-tricks.com/definition-tag/#comments Mon, 05 Apr 2021 15:54:34 +0000 https://css-tricks.com/?p=337804 It’s <dfn. Jen Kramer and Erika Lee are doing a #30DaysofHTML email list thing-y on Substack, which is an easy subscribe. It’s only been a few days and all of them have little gems, even for someone like me …


Definition Tag originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
It’s <dfn>. Jen Kramer and Erika Lee are doing a #30DaysofHTML email list thing-y on Substack, which is an easy subscribe. It’s only been a few days and all of them have little gems, even for someone like me who likes to think he has a pretty decent grasp on HTML. Day 4 is <dfn>.

I’m sure I could have told you that <dfn> was “definition” but I certainly don’t reach for it as often as I probably should and couldn’t give you a straight answer on the perfect time to use it.

I think Erika nails that here:

<p>He is not as enamored with <dfn id="kong">King Kong</dfn> 
  who resembles an enormous gorilla-like ape that has appeared 
  in various media since 1933. </p> 

...

<p>Complaints about <a href="#kong">Kong</a> include how he 
  has no atomic fire breath.</p> 

I really like the idea of defining a term naturally and contextually within a block of text, and pointing back up to it with an anchor link later if needed.

To Shared LinkPermalink on CSS-Tricks


Definition Tag originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/definition-tag/feed/ 1 337804
Smarter Ways to Generate a Deep Nested HTML Structure https://css-tricks.com/smarter-ways-to-generate-a-deep-nested-html-structure/ https://css-tricks.com/smarter-ways-to-generate-a-deep-nested-html-structure/#comments Tue, 20 Oct 2020 22:45:50 +0000 https://css-tricks.com/?p=322616 A look at using HTML preprocessors to generate HTML, particularly deeply nested HTML, which is useful for a variety of interesting browser art and experimentation.


Smarter Ways to Generate a Deep Nested HTML Structure originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Let’s say we want to have the following HTML structure:

<div class='boo'>
  <div class='boo'>
    <div class='boo'>
      <div class='boo'>
        <div class='boo'></div>
      </div>
    </div>
  </div>
</div>

That’s real a pain to write manually. And the reason why this post was born was being horrified on seeing it generated with Haml like this:

.boo
  .boo
    .boo
      .boo
        .boo

There were actually about twenty levels of nesting in the code I saw, but maybe some people are reading thing on a mobile phone, so let’s not fill the entire viewport with boos, even if Halloween is near.

As you can probably tell, manually writing out every level is far from ideal, especially when the HTML is generated by a preprocessor (or from JavaScript, or even a back-end language like PHP). I’m personally not a fan of deep nesting and I don’t use it much myself, but if you’re going for it anyway, then I think it’s worth doing in a manner that scales well and is easily maintainable.

So let’s first take a look at some better solutions for this base case and variations on it and then see some fun stuff done with this kind of deep nesting!

The base solution

What we need here is a recursive approach. For example, with Haml, the following bit of code does the trick:

- def nest(cls, n);
-  return '' unless n > 0;
-  "<div class='#{cls}'>#{nest(cls, n - 1)}</div>"; end

= nest('👻', 5)

There’s an emoji class in there because we can and because this is just a fun little example. I definitely wouldn’t use emoji classes on an actual website, but in other situations, I like to have a bit of fun with the code I write.

We can also generate the HTML with Pug:

mixin nest(cls, n)
  div(class=cls)
    if --n
      +nest(cls, n)

+nest('👻', 5)

Then there’s also the JavaScript option:

function nest(_parent, cls, n) {
  let _el = document.createElement('div');
	
  if(--n) nest(_el, cls, n);

  _el.classList.add(cls);
  _parent.appendChild(_el)
};

nest(document.body, '👻', 5)

With PHP, we can use something like this:

<?php
function nest($cls, $n) {
  echo "<div class='$cls'>";
  if(--$n > 0) nest($cls, $n);
  echo "</div>";
}

nest('👻', 5);
?>

Note that the main difference between what each of these produce is related to formatting and white space. This means that targeting the innermost “boo” with .👻:empty is going to work for the Haml, JavaScript and PHP-generated HTML, but will fail for the Pug-generated one.

Adding level indicators

Let’s say we want each of our boos to have a level indicator as a custom property --i, which could then be used to give each of them a different background, for example.

You may be thinking that, if all we want is to change the hue, then we can do that with filter: hue-rotate() and do without level indicators. However, hue-rotate() doesn’t only affect the hue, but also the saturation and lightness. It also doesn’t provide the same level of control as using our own custom functions that depend on a level indicator, --i.

For example, this is something I used in a recent project in order to make background components smoothly change from level to level (the $c values are polynomial coefficients):

--sq: calc(var(--i)*var(--i)); /* square */
--cb: calc(var(--sq)*var(--i)); /* cube */
--hue: calc(#{$ch0} + #{$ch1}*var(--i) + #{$ch2}*var(--sq) + #{$ch3}*var(--cb));
--sat: calc((#{$cs0} + #{$cs1}*var(--i) + #{$cs2}*var(--sq) + #{$cs3}*var(--cb))*1%);
--lum: calc((#{$cl0} + #{$cl1}*var(--i) + #{$cl2}*var(--sq) + #{$cl3}*var(--cb))*1%);

background: hsl(var(--hue), var(--sat), var(--lum));

Tweaking the Pug to add level indicators looks as follows:

mixin nest(cls, n, i = 0)
  div(class=cls style=`--i: ${i}`)
    if ++i < n
      +nest(cls, n, i)

+nest('👻', 5)

The Haml version is not too different either:

- def nest(cls, n, i = 0);
-   return '' unless i < n;
-   "<div class='#{cls}' style='--i: #{i}'>#{nest(cls, n, i + 1)}</div>"; end

= nest('👻', 5)

With JavaScript, we have:

function nest(_parent, cls, n, i = 0) {
  let _el = document.createElement('div');

  _el.style.setProperty('--i', i);
	
  if(++i < n) nest(_el, cls, n, i);

  _el.classList.add(cls);
  _parent.appendChild(_el)
};

nest(document.body, '👻', 5)

And with PHP, the code looks like this:

<?php
function nest($cls, $n, $i = 0) {
  echo "<div class='$cls' style='--i: $i'>";
  if(++$i < $n) nest($cls, $n, $i);
  echo "</div>";
}

nest('👻', 5);
?>

A more tree-like structure

Let’s say we want each of our boos to have two boo children, for a structure that looks like this:

.boo
  .boo
    .boo
      .boo
      .boo
    .boo
      .boo
      .boo
  .boo
    .boo
      .boo
      .boo
    .boo
      .boo
      .boo

Fortunately, we don’t have to change our base Pug mixin much to get this (demo):

mixin nest(cls, n)
  div(class=cls)
    if --n
      +nest(cls, n)
      +nest(cls, n)

+nest('👻', 5)

The same goes for the Haml version:

- def nest(cls, n);
-   return '' unless n > 0;
-   "<div class='#{cls}'>#{nest(cls, n - 1)}#{nest(cls, n - 1)}</div>"; end

= nest('👻', 5)

The JavaScript version requires a bit more effort, but not too much:

function nest(_parent, cls, n) {
  let _el = document.createElement('div');
  
  if(n > 1) {
    nest(_el, cls, n - 1);
    nest(_el, cls, n - 1)
  }

  _el.classList.add(cls);
  _parent.appendChild(_el)
};

nest(document.body, '👻', 5)

With PHP, we only need to call the nest() function once more in the if block:

<?php
function nest($cls, $n) {
  echo "<div class='$cls'>";
  if(--$n > 0) {
    nest($cls, $n);
    nest($cls, $n);
  }
  echo "</div>";
}

nest('👻', 5);
?>

Styling the top level element differently

We could of course add a special .top (or .root or anything similar) class only for the top level, but I prefer leaving this to the CSS:

:not(.👻) > .👻 {
  /* Top-level styles*/
}

Watch out!

Some properties, such as transform, filter, clip-path, mask or opacity don’t only affect an element, but also also all of its descendants. Sometimes this is the desired effect and precisely the reason why nesting these elements is preferred to them being siblings.

However, other times it may not be what we want, and while it is possible to reverse the effects of transform and sometimes even filter, there’s nothing we can do about the others. We cannot, for example, set opacity: 1.25 on an element to compensate for its parent having opacity: .8.

Examples!

First off, we have this pure CSS dot loader I recently made for a CodePen challenge:

Here, the effects of the scaling transforms and of the animated rotations add up on the inner elements, as do the opacities.

Next up is this yin and yang dance, which uses the tree-like structure:

For every item, except the outermost one (:not(.☯️) > .☯️), the diameter is equal to half of that of its parent. For the innermost items (.☯️:empty, which I guess we can call the tree leaves), the background has two extra radial-gradient() layers. And just like the first demo, the effects of the animated rotations add up on the inner elements.

Another example would be these spinning candy tentacles:

Each of the concentric rings represents a level of nesting and combines the effects of the animated rotations from all of its ancestors with its own.

Finally, we have this triangular openings demo (note that it’s using individual transform properties like rotate and scale so the Experimental Web Platform features flag needs to be enabled in chrome://flags in order to see it working in Chromium browsers):

Triangular openings (live demo).

This uses a slightly modified version of the basic nesting mixin in order to also set a color on each level:

- let c = ['#b05574', '#f87e7b', '#fab87f', '#dcd1b4', '#5e9fa3'];
- let n = c.length;

mixin nest(cls, n)
  div(class=cls style=`color: ${c[--n]}`)
    if n
      +nest(cls, n)

body(style=`background: ${c[0]}`)
  +nest('🔺', n)

What gets animated here are the individual transform properties scale and rotate. This is done so that we can set different timing functions for them.


Smarter Ways to Generate a Deep Nested HTML Structure originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/smarter-ways-to-generate-a-deep-nested-html-structure/feed/ 12 322616
Styling Complex Labels https://css-tricks.com/styling-complex-labels/ https://css-tricks.com/styling-complex-labels/#comments Mon, 05 Oct 2020 19:24:06 +0000 https://css-tricks.com/?p=322577 Danielle Romo covers the HTML pattern you need when you have a wordy <label> with fancy styling for an <input type="radio">.

The trick? The ol’ <span class="hidden-visually"> that contains the label that you want to be read, and a …


Styling Complex Labels originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Danielle Romo covers the HTML pattern you need when you have a wordy <label> with fancy styling for an <input type="radio">.

The trick? The ol’ <span class="hidden-visually"> that contains the label that you want to be read, and a <span aria-hidden="true"> with the visual-only content.


I think it’s interesting how often people are landing on this pattern. Have you seen Ethan’s The World-Wide Work? The drop-cap pattern he talks about here lands on essentially the same pattern.

<span aria-hidden="true">
  Markup for the visual experience only,
  where you can (somewhat safely) use markup 
  that would be crap for screen readers.  
</span>

<span class="visually-hidden">
  Markup for the read experience only, that
  you keep very clean on purpose.
</span>

That class is like this.

To Shared LinkPermalink on CSS-Tricks


Styling Complex Labels originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/styling-complex-labels/feed/ 2 322577
Editing HTML Like A Boss In VS Code https://css-tricks.com/editing-html-like-a-boss-in-vs-code/ https://css-tricks.com/editing-html-like-a-boss-in-vs-code/#comments Wed, 16 Sep 2020 14:50:45 +0000 https://css-tricks.com/?p=321004 Here’s a seven minute video from Caleb Porzio that focuses on some of Emmet‘s HTML editing features. You might think of Emmet as that thing that expands abbreviations like table.stats>tr*3>td*3 into glorious, expanded, and perfect HTML. But Emmet has …


Editing HTML Like A Boss In VS Code originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Here’s a seven minute video from Caleb Porzio that focuses on some of Emmet‘s HTML editing features. You might think of Emmet as that thing that expands abbreviations like table.stats>tr*3>td*3 into glorious, expanded, and perfect HTML. But Emmet has other HTML editing trickery up its sleeve. My favorite is “wrap with abbreviation” (which happens to be Cmd/Ctrl + Shift + A on CodePen), but there are more, like expanding your selection inward and outward and tag changing.

If you haven’t seen it, the Emmet 2 preview on CodePen is pretty neeeeat. It shows you what you’re about to expand into before you do it:

To Shared LinkPermalink on CSS-Tricks


Editing HTML Like A Boss In VS Code originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/editing-html-like-a-boss-in-vs-code/feed/ 1 321004