less / less.ruby

Less Ruby — now at http://github.com/cowboyd/less.rb
Apache License 2.0
957 stars 69 forks source link

Introduce an option to mangle compilation results #180

Closed paulmillr closed 6 years ago

paulmillr commented 13 years ago

tl; dr: I propose to add an option that would compile this

.photos
  .photo
    .description

to

.photos {}
  .photos-photo {}
    .photos-photo-description {}

What

In the most of today's heavy webapps, styles are very unstructured.

Dynamic CSS-like languages (less, sass, stylus) allow selector nesting, like:

.users
  padding: 2px
  .user
    padding: 10px
    .avatar
      padding: 16px

Cost

It is an awesome and very structured way to describe styles.

Although, that approach has one major issue: the descendant selector is the most expensive selector in CSS. Really, it is dreadfully expensive. While this expensiveness is totally OK for small sites, it is a pain for big and fat ones.

In my webapps, I usually use five and more indented levels. Comprehensive example: paulmillr/vk-contest-2011/css/style.css#L450.

Idea

To deal with performance issues in big webapps, user would be able to use some new compilation option, like --mangle, that would mangle all descendant selectors with some symbol, that would be used for namespace resolution. Like _ or -.

So, instead of this

.wall {
  border: 1px solid #696; }
  .wall-posts {
    padding-top: 7px; }
    .wall-post {
      padding: 12px 0 6px 1px;
      border-top: 1px solid #ededed; }
      .wall-post-avatar {
        position: absolute;
        display: block;
        width: 50px;
        height: 50px; }
      .wall-post-content {
        margin-left: 50px;
        padding-left: 13px; }
        .wall-post-initials {
          font-weight: bold;
          color: #4f6b8d; }
          .wall-post-initials:hover {
            text-decoration: underline; }
        .wall-post-text {
          padding: 3px 0; }
        .wall-post-attachment {
          padding: 5px 0; }
          .wall-post-attachment-type-photo {
            float: left;
            padding-right: 15px; }
          .wall-post-attachment-label {
            font-weight: bold;
            color: #888; }
          .wall-post-attachment-photo {
            margin: 0; }
          .wall-post-article-photo {
            position: absolute;
            padding-top: 5px; }
            .wall-post-article-photo-image {
              width: 75px;
              max-height: 98px; }
          .wall-post-attachment-info {
            margin-left: 85px; }
            .wall-post-attachment-info.no-attachment-photo {
              margin-left: 0; }
            .wall-post-attachment-title {
              font-weight: bold; }
            .wall-post-attachment-title:hover {
              text-decoration: underline; }
        .wall-post-footer {
          padding-bottom: 3px;
          line-height: 20px; }
          .wall-post-date {
            color: #aaa; }
            .wall-post-date:hover {
              text-decoration: underline; }

it would be much more comroftable to write something like this:

.wall {
  border: 1px solid #696; }
  .posts {
    padding-top: 7px; }
    .post {
      padding: 12px 0 6px 1px;
      border-top: 1px solid #ededed; }
      .avatar {
        position: absolute;
        display: block;
        width: 50px;
        height: 50px; }
      .content {
        margin-left: 50px;
        padding-left: 13px; }
        .initials {
          font-weight: bold;
          color: #4f6b8d; }
          .initials:hover {
            text-decoration: underline; }
        .text {
          padding: 3px 0; }
        .attachment {
          padding: 5px 0; }
          .type-photo {
            float: left;
            padding-right: 15px; }
          .label {
            font-weight: bold;
            color: #888; }
          .photo {
            margin: 0; }
          .article-photo {
            position: absolute;
            padding-top: 5px; }
            .image {
              width: 75px;
              max-height: 98px; }
          .info {
            margin-left: 85px; }
            .info.no-attachment-photo {
              margin-left: 0; }
            .title {
              font-weight: bold; }
              &:hover {
                text-decoration: underline; }
        .footer {
          padding-bottom: 3px;
          line-height: 20px; }
          .date {
            color: #aaa; }
            &:hover {
              text-decoration: underline; }
thelitek commented 12 years ago

I couldn't find in the docs, nor confirm in other comipilers (tested only in less.app and less.php online demo) but I was able to achieve this with pain old & that seems to work like a string, so:

.photos {
    &-photo {
        &-description {}
    }
}

should compile to:

.photos {}
.photos-photo {}
.photos-photo-description {}