Tambahkan elemen ke aturan Less CSS

Saya mencoba mengatur gaya tampilan elemen yang berbeda berdasarkan tipenya, sambil mencocokkan serangkaian aturan menggunakan lebih sedikit.

Menggunakan & setelah aturan ditentukan akan menambahkan tipe elemen ke akhir aturan dan dengan atau tanpa spasi, ini jelas tidak berfungsi.

Saya yakin ada cara yang tidak terlalu berulang dan lebih optimal untuk menulis yang berikut ini:

&.admin {
    .service_provider.security_class_admin,
    .service_provider.security_class_admin_manager,
    .service_provider.security_class_admin_user,
    .service_provider.security_class_admin_manager_user {
        display: block;
    }
    th {
        &.service_provider.security_class_admin,
        &.service_provider.security_class_admin_manager,
        &.service_provider.security_class_admin_user,
        &.service_provider.security_class_admin_manager_user {
            display: table-cell;
        }
    }
    button {
        &.service_provider.security_class_admin,
        &.service_provider.security_class_admin_manager,
        &.service_provider.security_class_admin_user,
        &.service_provider.security_class_admin_manager_user {
            display: inline-block;
        }
    }
}

Saya akan sangat menghargai bantuan dalam menemukan solusi terbaik untuk ini.


person user2115620    schedule 13.06.2016    source sumber


Jawaban (2)


Saat ini, tidak ada cara untuk menyisipkan pemilih di tengah rantai pemilih. Itu dapat ditambahkan di awal atau di akhir saja. Menambahkan di akhir tidak akan berhasil untuk kasus Anda karena pemilih jenis elemen hanya bisa berada di awal.

Anda dapat menggunakan mixin tulis sedemikian rupa sehingga memiliki semua penyeleksi umum dan menerima kumpulan aturan sebagai masukan.

&.admin{
    .common-selectors({display: block;});
    th{
        .common-selectors({display: table-cell;}, append);
    }
    button{
        .common-selectors({display: inline-block;}, append);
    }
}

.common-selectors(@props, @type:child){
    & when (@type = append) { /* type check because the element type is appended */
        &.service_provider.security_class_admin,
        &.service_provider.security_class_admin_manager,
        &.service_provider.security_class_admin_user,
        &.service_provider.security_class_admin_manager_user{
            @props();
        }
    }
    & when not (@type = append) { /* type check because default shouldn't be appended */
        .service_provider.security_class_admin,
        .service_provider.security_class_admin_manager,
        .service_provider.security_class_admin_user,
        .service_provider.security_class_admin_manager_user{
            @props();
        }
    }    
}

Cuplikan berdasarkan hasil kompilasi dari kode di atas:

.admin .service_provider.security_class_admin,
.admin .service_provider.security_class_admin_manager,
.admin .service_provider.security_class_admin_user,
.admin .service_provider.security_class_admin_manager_user {
  display: block;
}
.admin th.service_provider.security_class_admin,
.admin th.service_provider.security_class_admin_manager,
.admin th.service_provider.security_class_admin_user,
.admin th.service_provider.security_class_admin_manager_user {
  display: table-cell;
}
.admin button.service_provider.security_class_admin,
.admin button.service_provider.security_class_admin_manager,
.admin button.service_provider.security_class_admin_user,
.admin button.service_provider.security_class_admin_manager_user {
  display: inline-block;
}
div,
span,
button,
th,
tr,
table {
  border: 1px solid;
  margin: 10px;
}
<div class='admin'>
  <div class='service_provider security_class_admin'>Admin</div>
  <div class='service_provider security_class_admin_manager'>Manager</div>
  <div class='service_provider security_class_admin_user'>User</div>
  <div class='service_provider security_class_admin_manager_user'>Manager User</div>
</div>
<div class='admin'>
  <span class='service_provider security_class_admin'>Admin</span>
  <span class='service_provider security_class_admin_manager'>Manager</span>
  <span class='service_provider security_class_admin_user'>User</span>
  <span class='service_provider security_class_admin_manager_user'>Manager User</span>
</div>
<div class='admin'>
  <button class='service_provider security_class_admin'>Admin</button>
  <button class='service_provider security_class_admin_manager'>Manager</button>
  <button class='service_provider security_class_admin_user'>User</button>
  <button class='service_provider security_class_admin_manager_user'>Manager User</button>
</div>
<table>
  <tr>
    <th class='service_provider security_class_admin'>Admin</th>
    <th class='service_provider security_class_admin_manager'>Manager</th>
    <th class='service_provider security_class_admin_user'>User</th>
    <th class='service_provider security_class_admin_manager_user'>Manager User</th>
  </tr>
</table>


Atau pendekatan yang lebih singkat untuk mixin adalah dengan menggunakan pemilih universal (*) untuk memblokir tampilan semua elemen.

&.admin{
    * {
        .common-selectors({display: block;});
    }
    th{
        .common-selectors({display: table-cell;});
    }
    button{
        .common-selectors({display: inline-block;});
    }
}

.common-selectors(@props, @type:child){
    &.service_provider.security_class_admin,
    &.service_provider.security_class_admin_manager,
    &.service_provider.security_class_admin_user,
    &.service_provider.security_class_admin_manager_user{
        @props();
    }
}

Cuplikan berdasarkan hasil kompilasi dari kode di atas:

.admin *.service_provider.security_class_admin,
.admin *.service_provider.security_class_admin_manager,
.admin *.service_provider.security_class_admin_user,
.admin *.service_provider.security_class_admin_manager_user {
  display: block;
}
.admin th.service_provider.security_class_admin,
.admin th.service_provider.security_class_admin_manager,
.admin th.service_provider.security_class_admin_user,
.admin th.service_provider.security_class_admin_manager_user {
  display: table-cell;
}
.admin button.service_provider.security_class_admin,
.admin button.service_provider.security_class_admin_manager,
.admin button.service_provider.security_class_admin_user,
.admin button.service_provider.security_class_admin_manager_user {
  display: inline-block;
}
div,
span,
button,
th,
tr,
table {
  border: 1px solid;
  margin: 10px;
}
<div class='admin'>
  <div class='service_provider security_class_admin'>Admin</div>
  <div class='service_provider security_class_admin_manager'>Manager</div>
  <div class='service_provider security_class_admin_user'>User</div>
  <div class='service_provider security_class_admin_manager_user'>Manager User</div>
</div>
<div class='admin'>
  <span class='service_provider security_class_admin'>Admin</span>
  <span class='service_provider security_class_admin_manager'>Manager</span>
  <span class='service_provider security_class_admin_user'>User</span>
  <span class='service_provider security_class_admin_manager_user'>Manager User</span>
</div>
<div class='admin'>
  <button class='service_provider security_class_admin'>Admin</button>
  <button class='service_provider security_class_admin_manager'>Manager</button>
  <button class='service_provider security_class_admin_user'>User</button>
  <button class='service_provider security_class_admin_manager_user'>Manager User</button>
</div>
<table>
  <tr>
    <th class='service_provider security_class_admin'>Admin</th>
    <th class='service_provider security_class_admin_manager'>Manager</th>
    <th class='service_provider security_class_admin_user'>User</th>
    <th class='service_provider security_class_admin_manager_user'>Manager User</th>
  </tr>
</table>

person Harry    schedule 13.06.2016
comment
bagus sekali, terima kasih Harry, ini pasti akan membantu mengoptimalkan berbagai hal. - person user2115620; 13.06.2016
comment
Tidak apa-apa. Saya sedang belajar KURANG saat ini dan ini adalah solusi yang bagus. Penggunaan mixin sangat membantu - person Marcos Pérez Gude; 13.06.2016
comment
@ user2115620: Saya sebenarnya membuat kesalahan yang menyebabkan keluaran mixin asli tidak sama dengan kode Anda. Saya sudah memodifikasinya sekarang, harap diperhatikan. Hal ini karena penyeleksi umum bekerja dalam dua cara. Ketika disarangkan di bawah tipe elemen, elemen tersebut harus ditambahkan ke induknya, sedangkan di luar pemilih tipe elemen, seharusnya tidak demikian. Jadi, perlu ada satu tingkat pemeriksaan lagi. - person Harry; 13.06.2016
comment
Pernyataan when () itu tidak saya ketahui. Terima kasih atas koreksinya :) - person Marcos Pérez Gude; 13.06.2016
comment
@MarcosPĆ©rezGude: Ini seperti konstruksi if. Periksa nilai variabel dan kemudian putuskan apakah isinya harus dieksekusi atau tidak :) - person Harry; 13.06.2016

Jadi terima kasih atas bantuan Anda, ditambah loop for-in yang saya pelajari dari postingan berikut: Cara menghasilkan CSS dengan loop dalam waktu lebih sedikit

Saya sekarang memiliki:

.for(@list, @code) {
        & {
            .loop(@i:1) when (@i =< length(@list)) {
                @value: extract(@list, @i);

                @code();

                .loop(@i + 1);
            }

            .loop();
        }
    }

    .role-varients(@orgType, @variants, @props, @type:child){
        .for(@variants, {
            & when (@type = append) {
                &.@{orgType}.security_class_@{value} {
                    @props();
                }
            }
            & when not (@type = append) {
                .@{orgType}.security_class_@{value} {
                    @props();
                }
            }
        });
    }
    @admin-roles: admin, admin_manager, admin_user, admin_manager_user;
    @manager-roles: manager, admin_manager, manager_user, admin_manager_user;
    @user-roles: user, admin_user, manager_user, admin_manager_user;
    &.service_provider{
        &.admin{
            .role-varients(service_provider, @admin-roles, {display: block;});
            th{
                .role-varients(service_provider, @admin-roles, {display: table-cell;}, append);
            }
            button{
                .role-varients(service_provider, @admin-roles, {display: inline-block;}, append);
            }
        }
        &.manager{
            .role-varients(service_provider, @manager-roles, {display: block;});
            th{
                .role-varients(service_provider, @manager-roles, {display: table-cell;}, append);
            }
            button{
                .role-varients(service_provider, @manager-roles, {display: inline-block;}, append);
            }
        }
        &.user{
            .role-varients(service_provider, @user-roles, {display: block;});
            th{
                .role-varients(service_provider, @user-roles, {display: table-cell;}, append);
            }
            button{
                .role-varients(service_provider, @user-roles, {display: inline-block;}, append);
            }
        }
    }
    &.client{
        &.admin{
            .role-varients(client, @admin-roles, {display: block;});
            th{
                .role-varients(client, @admin-roles, {display: table-cell;}, append);
            }
            button{
                .role-varients(client, @admin-roles, {display: inline-block;}, append);
            }
        }
        &.manager{
            .role-varients(client, @manager-roles, {display: block;});
            th{
                .role-varients(client, @manager-roles, {display: table-cell;}, append);
            }
            button{
                .role-varients(client, @manager-roles, {display: inline-block;}, append);
            }
        }
        &.user{
            .role-varients(client, @user-roles, {display: block;});
            th{
                .role-varients(client, @user-roles, {display: table-cell;}, append);
            }
            button{
                .role-varients(client, @user-roles, {display: inline-block;}, append);
            }
        }
    }
    &.vendor{
        &.admin{
            .role-varients(vendor, @admin-roles, {display: block;});
            th{
                .role-varients(vendor, @admin-roles, {display: table-cell;}, append);
            }
            button{
                .role-varients(vendor, @admin-roles, {display: inline-block;}, append);
            }
        }
        &.manager{
            .role-varients(vendor, @manager-roles, {display: block;});
            th{
                .role-varients(vendor, @manager-roles, {display: table-cell;}, append);
            }
            button{
                .role-varients(vendor, @manager-roles, {display: inline-block;}, append);
            }
        }

        &.user{
            .role-varients(vendor, @user-roles, {display: block;});
            th{
                .role-varients(vendor, @user-roles, {display: table-cell;}, append);
            }
            button{
                .role-varients(vendor, @user-roles, {display: inline-block;}, append);
            }
        }
    }

Saya akan menggunakan loop for lain untuk menangani 3 blok utama [penyedia_layanan, klien, vendor] tetapi saat saya menggunakan .@{value} Saya kira cakupannya rusak karena memiliki loop dalam satu loop dan tidak memberikan hasil yang diharapkan .

Meskipun hal di atas masih terkesan panjang, namun yang pasti lebih baik daripada menulis setiap aturan secara manual.

Solusi saya muncul berkat masukan Harry jadi saya kira saya harus menandai jawabannya sebagai benar? Sekali lagi terima kasih semuanya ;)

person user2115620    schedule 13.06.2016
comment
Penandaan penerimaan sepenuhnya merupakan pilihan Anda, tetapi aturan umumnya adalah menerima jawaban yang menjawab pertanyaan awal secara lengkap. Hal tambahan apa pun yang telah Anda lakukan untuk memperbaiki jawaban tersebut dapat diposting karena dapat bermanfaat bagi orang lain. Jika jawaban yang lain hanya sebagian dan jawaban Anda lengkap dari pertanyaan awal, maka Anda menerima jawaban Anda :) - person Harry; 13.06.2016
comment
terima kasih atas bimbingannya Harry - jawaban Anda memecahkan masalah asli untuk saya, saya baru saja mengembangkannya;) - person user2115620; 14.06.2016