I am building a flexbox grid system and am looking to keep my scss file manageable.
What is wrong with the selectors for elements with classes col-2, col-4, col-6 that are causing them not to work?
.grid-container{
max-width:1280;
margin: 0 24px;
display: flex;
[class^="col"]{
flex:1;
margin: 0 8px;
&:first-child{
margin-left:0;
}
&:last-child{
margin-right:0;
}
[class*="-2"]{
width:16.5%;
}
[class*="-4"]{
width:33%;
}
[class*="-6"]{
width:50%;
}
}
}
All columns are getting the styling for margin and the first-child and last-child behavior but not the width from the other selectors. Is this perhaps a flexbox issue? flex-basis?
It's not a "flexbox" issue. It's a "CSS" issue.
[class^="col"] {
[class*="-2"] {
width:16.5%;
}
}
will result in this CSS:
[class^="col"] [class*="-2"]{width:16.5%;}
But you probably want...
[class^="col"][class*="-2"]{width:16.5%;}
... which would be produced by...
[class^="col"] {
&[class*="-2"] {
width:16.5%;
}
}
The space (in CSS) and the ampersand
&
(in SCSS) are the differences.
[class^="col"] {
[class*="-2"] {
width: 16.5%;
}
[class*="-4"] {
width: 33%;
}
[class*="-6"] {
width: 50%;
}
}
Will produce the following selectors:
[class^="col"] [class*="-2"] {}
[class^="col"] [class*="-4"] {}
[class^="col"] [class*="-6"] {}
Notice the space between each attribute selector. The selectors above will first search for and element that has a class attribute that starts with the .col
class. They then find an element nested within the .col
element with a class attribute that contains -2
, -4
or -6
somewhere in the attribute.
By adding an ampersand &
you can capture the current selector path. The following SCSS is the same as what you have now:
[class^="col"] {
& [class*="-2"] {
width: 16.5%;
}
}
Compiles to (space between attribute selectors):
[class^="col"] [class*="-2"] {}
Placing the ampersand immediately before the nested selector (like you have with first-child
and last-child
) gives a different result, the one you (likely) want:
[class^="col"] {
&[class*="-2"] {
width: 16.5%;
}
}
Compiles to (no space between attribute selectors):
[class^="col"][class*="-2"] {}
IMHO what you have currently is over engineered. I'd suggest something more straightforward and flexible. Use regular class selectors.
.col {
&-2 { width: 16.5%; }
&-4 { width: 33%; }
&-6 { width: 50%; }
}
[class*="col-"] {
flex: 1;
margin: 0 8px;
&:first-child { margin-left: 0; }
&:last-child { margin-right: 0; }
}
See below Stack Snippet to see what the above is compiled to. Note that I used *=
(asterisk equals) instead of ^=
(caret equals) for class placement flexibility. Up to you if you want to enforce column classes to be the first class in the class attribute value.
https://codepen.io/anon/pen/yXveRq
.row { display: flex; } .col-2 { width: 16.5%; } .col-4 { width: 33%; } .col-6 { width: 50%; } [class*="col-"] { flex: 1; margin: 0 8px; } [class*="col-"]:first-child { margin-left: 0; } [class*="col-"]:last-child { margin-right: 0; }
<div class="row"> <div class="col-4">Col 1</div> <div class="col-4">Col 2</div> <div class="col-4">Col 3</div> </div>
CoJanks. The quick and dirt fix is to set additional definitions to the 'flex' on the .col class in the .grid-container.
Here is a quick and dirty answer to solve your problem for ya!
flex:1 1 auto;
FYI. There were some discrepancies in class nesting as well that I covered in the link provided.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.