Classless form inputs with icons

by Andy Prevost

Wednesday August 13 2025

A comment to start: watching the status of Classless and Class-light frameworks ... nice to see some major progress in this area. One Class-light framework has gone a bit too far though. The Class-light should not venture too far into the 12-grid mindset. Keep in mind that the 12-grid framework came into being to achieve a granular framework with flexibility. And it worked – for its time. We now have Grid Layout. The process of creating grids is now far easier than ever and we are not tied to 12 column grids and the complexity of writing code that it entails. I've written a grid layout that can accommodate any number of columns (including 60 and even more if needed) with a total of 10 lines of code. Stick to the task at hand, we need more flexibility and more powerful frameworks that are classless.

Now let's discuss the next steps in classless. I've been working on forms and have created a module for inputs with icons. Icons on the left, icons on the right. This module, however, is not classless. I turned my attention to creating a new module that looked at providing icons with the appearance of being inside the input element and classless. 

I've achieved it. And all within 52 lines of code. And classless, completely. First, let's define what I mean by this. For the icons, I am stayed with Font Awesome ... the 4.7.0 version. That uses classes, can't get away from it. I could have used SVG icons, I guess, but that would have required classes too. I figured it would be a lot simpler, and easier, to just stick with Font Awesome. I based all of my icons on version 4.7.0 of Font Awesome ... largely because I did not agree with the licensing scheme used after that version. Font Awesome 4.7.0 is loaded by CDN.

In this article, I won't go over the base CSS for my inputs. It is part of my CSS Blade framework, all basic stuff with no classes for inputs, but there is font size and padding involved. I mention that because it affects the spacing for the icons.

Here's what I want the HTML code to look like:

<div>
  <label for="name">Text Input</label>
  <i class="fa fa-user fa-lg" aria-hidden="true"></i>
  <input type="text" id="name" name="name" placeholder="Your name">
</div>

Again, I want to point out the icon is based on Font Awesome which requires a class. I think that is a reasonable compromise to get icons. And I also point out that there is no way of getting icons in an input without using a class. What I want, though, is that all the other HTML remain classless. No wrappers for the input grouping, no wrappers for the icon grouping or positioniong. Semantic HTML only.

The above example is exactly what I want for a left aligned icon. For right aling icions, I believe the icon tag should be after the input tag ... as in:

<div>
  <label for="name">Text Input</label>
  <input type="text" id="name" name="name" placeholder="Your name">
  <i class="fa fa-check fa-lg" aria-hidden="true"></i>
</div>

If you want an icon at the left and an icon at the right, put an icon above the input tag and below the input tag.

Here's the CSS:

div:has(label) {
  background-color:white;
  position: relative;
  margin-bottom:10px;
}
div > label {
  display:block;
  font-size:80%;
}
div > label + i.fa {
  background-color: #eee;
  border-right: 1px dotted var(–border);
  color: #aaa;
  line-height:1.5;
  max-width:1.5em;
  position: relative;
    top: 2px;
    right:auto;
    bottom:2px !important;
    left:2px;
  text-align:center;
  width:1.5em;
  +input {
    background-color:transparent;
    position:absolute;
      left:0;
    padding-left: calc(2em + 3px);
    width:100%;
    + i.fa {
      color:green;
      position:absolute;
        right:10px;
      line-height:1.5;
    }
  }  
}
div > label + input {
  position: absolute;
  + i.fa {
  background-color: #eee;
  border-left: 1px dotted var(–border);
  color: #aaa;
  line-height:1.5;
  max-width:1.5em;
  position: relative;
    top: 2px;
    right:2px;
    bottom:2px !important;
    left:calc(100% - 1.5em - 2px);
  text-align:center;
  width:1.5em;
}

I had originally written that this was achieved with 53 lines of code ... I forgot one of those lines was a test line that had a border to show position ... took that out and it is actually only 52 lines of code.

Simple. And it works. It is based on having a label though. What if you want to take the label out and use the placeholder instead? Working on that now.

Stay tuned.

PS. one more comment about the state of Classless frameworks. One of the latest framework authors published some comments about his new project. Totally turned me off. Up that point, I had wanted to test out his work ... but when he stated that he wanted to use data- attributes to change the tag css, meant his project was a total waste of time. Why would anyone replace classes with data- attributes? It means the same as classes, just adds a new level of complexity.

 

 

◀ Previous Next ▶

Post a Comment