เพิ่มองค์ประกอบลงในกฎ Less CSS

ฉันกำลังพยายามตั้งค่ารูปแบบการแสดงผลขององค์ประกอบต่างๆ ตามประเภทขององค์ประกอบ ในขณะที่จับคู่ชุดกฎโดยใช้น้อยกว่า

การใช้ & หลังจากกำหนดกฎแล้ว จะเพิ่มประเภทองค์ประกอบต่อท้ายกฎ และไม่ว่าจะมีหรือไม่มีการเว้นวรรค ซึ่งเห็นได้ชัดว่าใช้งานไม่ได้

ฉันแน่ใจว่ามีวิธีที่ซ้ำซากน้อยกว่าและเหมาะสมกว่าในการเขียนสิ่งต่อไปนี้:

&.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;
        }
    }
}

ฉันขอขอบคุณความช่วยเหลือในการหาทางออกที่ดีที่สุดสำหรับเรื่องนี้


person user2115620    schedule 13.06.2016    source แหล่งที่มา


คำตอบ (2)


ขณะนี้ยังไม่มีวิธีแทรกตัวเลือกไว้ตรงกลางของห่วงโซ่ตัวเลือก สามารถเพิ่มได้เฉพาะตอนเริ่มต้นหรือตอนท้ายเท่านั้น การเพิ่มที่ส่วนท้ายจะไม่ทำงานสำหรับกรณีของคุณ เนื่องจากตัวเลือกประเภทองค์ประกอบจะอยู่ได้เฉพาะที่จุดเริ่มต้นเท่านั้น

คุณสามารถใช้เขียนมิกซ์อินเพื่อให้มีตัวเลือกทั่วไปทั้งหมดและยอมรับชุดกฎเป็นอินพุต

&.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();
        }
    }    
}

ตัวอย่างข้อมูลตามเอาต์พุตที่คอมไพล์ของโค้ดด้านบน:

.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>


หรือแนวทางที่สั้นกว่าสำหรับมิกซ์อินคือการใช้ตัวเลือกสากล (*) เพื่อบล็อกการแสดงผลสำหรับองค์ประกอบทั้งหมด

&.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();
    }
}

ตัวอย่างข้อมูลตามเอาต์พุตที่คอมไพล์ของโค้ดด้านบน:

.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
เยี่ยมเลย ขอบคุณแฮร์รี่ นี่จะช่วยเพิ่มประสิทธิภาพสิ่งต่างๆ ได้อย่างแน่นอน - person user2115620; 13.06.2016
comment
ไม่เป็นไร. ตอนนี้ฉันกำลังเรียนรู้น้อยลง และนี่เป็นทางออกที่ดี การใช้มิกซ์อินช่วยได้จริงๆ - person Marcos Pérez Gude; 13.06.2016
comment
@ user2115620: จริง ๆ แล้วฉันทำผิดพลาดเพราะว่าผลลัพธ์ของมิกซ์อินดั้งเดิมจะไม่เหมือนกับรหัสของคุณ ฉันได้แก้ไขมันแล้ว โปรดรับทราบ เนื่องจากตัวเลือกทั่วไปทำงานในสองวิธี เมื่อซ้อนกันภายใต้ประเภทองค์ประกอบ ควรต่อท้ายองค์ประกอบเหล่านั้นกับพาเรนต์ ในขณะที่องค์ประกอบที่อยู่นอกตัวเลือกประเภทองค์ประกอบไม่ควรเป็นเช่นนั้น ดังนั้นจึงจำเป็นต้องตรวจสอบเพิ่มอีกระดับหนึ่ง - person Harry; 13.06.2016
comment
ฉันไม่รู้จักคำสั่ง when () นั้น ขอบคุณสำหรับการแก้ไขค่ะ :) - person Marcos Pérez Gude; 13.06.2016
comment
@ MarcosPérezGude: มันเหมือนกับโครงสร้าง if ตรวจสอบค่าของตัวแปรแล้วตัดสินใจว่าควรดำเนินการเนื้อหาหรือไม่ :) - person Harry; 13.06.2016

ขอขอบคุณสำหรับความช่วยเหลือของคุณ รวมถึง for-in loop ที่ฉันได้เรียนรู้จากโพสต์ต่อไปนี้: วิธีสร้าง CSS ด้วยการวนซ้ำในเวลาน้อยลง

ตอนนี้ฉันมี:

.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);
            }
        }
    }

ฉันจะใช้ for loop อันอื่นเพื่อจัดการ 3 บล็อกหลัก [service_provider, client, vendor] แต่ที่ฉันใช้ .@{value} ฉันเดาว่าขอบเขตใช้งานไม่ได้จากการมีลูปภายในลูปและมันไม่ได้ให้ผลลัพธ์ที่คาดหวัง .

แม้ว่าข้อความข้างต้นจะดูยาว แต่ก็ดีกว่าการเขียนกฎแต่ละข้อด้วยตนเองอย่างแน่นอน

วิธีแก้ปัญหาของฉันเกิดจากการป้อนข้อมูลของ Harry ดังนั้นฉันเดาว่าฉันควรทำเครื่องหมายคำตอบของเขาว่าถูกต้องหรือไม่ ขอบคุณทุกคนอีกครั้ง;)

person user2115620    schedule 13.06.2016
comment
การทำเครื่องหมายการยอมรับเป็นทางเลือกของคุณโดยสิ้นเชิง แต่กฎทั่วไปคือการยอมรับคำตอบที่ตอบคำถามเดิมทั้งหมด คุณสามารถโพสต์ข้อมูลเพิ่มเติมใด ๆ ที่คุณทำเพื่อปรับปรุงคำตอบนั้นได้เนื่องจากจะเป็นประโยชน์ต่อผู้อื่น หากคำตอบอื่นเป็นคำตอบบางส่วนและคำตอบของคุณเป็นคำตอบที่สมบูรณ์สำหรับคำถามเดิม แสดงว่าคุณยอมรับคำตอบของคุณ :) - person Harry; 13.06.2016
comment
ขอบคุณสำหรับคำแนะนำแฮร์รี่ - คำตอบของคุณแก้ไขปัญหาเดิมสำหรับฉันแล้ว ฉันเพิ่งสร้างมันขึ้นมา;) - person user2115620; 14.06.2016