简体   繁体   中英

SCSS target classes and pseudo selectors simultaneously

I'm writing a library and I'd like to style all buttons.

HTML

<div>
  <p>Buttons</p>
  <button>Button</button>
  <button class="r1">Button</button>
</div>

<div>
  <p>File inputs</p>
  <input type="file" />
  <input type="file" class="r1" />
</div>

SCSS

button,
input[type=file]::file-selector-button {
  background: #81ecec;
  border: 2px solid #00cec9;
  &.r1{
    background: red;
  }
}

This code processes to:

button.r1,
input[type=file]::file-selector-button.r1 {
  background: red;
}

[This is invalid and does not work]

Is there a mixin or method I can use so that I can place the classes on only the parent selector, without this getting out of hand? I intend to have multiple classes ( primary , secondary , large , small ) and I don't want to write :

button.r1,
input[type=file].r1::file-selector-button{
  ...
}

button.large,
input[type=file].large::file-selector-button{
   ...
}

button.small,
input[type=file].small::file-selector-button{
   ...
}

I can't figure out a good way of targeting the parent input[type="file"]

This codepen has the first example in it, and as it isn't valid CSS the background: red doesn't take effect:

https://codepen.io/EightArmsHQ/pen/VwxwPGM/139933ae274200149b84afdb726478c5?editors=1100

Attempt 1

At the moment I am using a mixin like so:

@mixin button{
  background: var(--button-primary);
  color: #fff;
  text-decoration: none;
  border: none;
  display: inline-block;
  padding: 4px 8px;
}

@mixin button-r1{
  border-radius: 3px;
}

button,
.button,
input[type="submit"],
input[type="reset"]{
  @include button;
  &.r1{
    @include button-r1;
  }
}

input[type=file]{
  &::file-selector-button{
    @include button;
  }
  &.r1::file-selector-button{
    @include button-r1;
  }
}

The benefit is that I don't need to repeat the same styles over and over, however I feel like there must be a better way of creating a mixin that interpolates a class somehow.

Attempt 2

Using the classname as an argument works well, however I lose the ability to nest the rules, which is a shame and one of my favourite parts of SCSS.

@mixin buttonAndFileInputs($classname: "") {
  button#{$classname},
  .button#{$classname},
  input[type="submit"]#{$classname},
  input[type="reset"]#{$classname}, 
  input[type="file"]#{$classname}::file-selector-button {
    @content;
  }
}


@include buttonAndFileInputs {
  background: var(--button-primary);
  color: #fff;
}

@include buttonAndFileInputs(".r1") {
  border-radius: 3px;
}

I'm not 100% clear on what you're trying to do

But I think if you edit your codepen to this scss

button,
input[type=file] {
  background: #81ecec;
  border: 2px solid #00cec9;
  &.r1{
    background: red;
  }
}

::file-selector-button {
  background: inherit;
  border: inherit;
}

that will get what you're looking for

Edit to add explanation : This will make the file-selector-button follow the background and border properties of the input[type=file] .
This means that the file-selector-button will match the rest of the input background.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM