-->

html label:after content needs to have different c

2019-07-29 18:32发布

问题:

I have the display name of my model properties set, but I need them to display with a colon if they're not required and a colon and a red asterisk if they are.

I didn't want to add the colon to the display name since I don't want the colon to appear in error messages and I may want to display them somewhere without it.

I used the following style in my HTML file for adding the colon:

.my-label > label:after {
        content: ": ";
}

However I can't figure out how to get a red asterisk to display after that if the field is required.

I could create another style class to include the asterisk, however if I change the color it's either all red or all black. I'm not sure I want to set the actual model property to be required because I'm not sure I want a universal rule stating that it is required.

Any suggestions of a better way to handle this would be welcome.

回答1:

The problem

It is not possible to use different colours in a single pseudo element. In this case you are able to output :* using the :after pseudo element but are not able to make the characters different colours.

Solution 1

One possible way to achieve what you are after is to use the :before pseudo element. The overriding issue, of course is that this will put the asterisk at the beginning of the label. You can fix this by making the label use the flexbox model. This will allow the order of the pseudo elements to be changed allowing you to place the :before element at the end of the label:

.my-label > label {
  display: inline-flex;
}
.my-label.required > label:before {
  color: red;
  content: "*";
  order: 1;
}
.my-label > label:after {
  content: ":";
}
<div class="my-label">
  <label>Not required</label>
  <input type="text" />
</div>
<div class="my-label required">
  <label>Required</label>
  <input type="text" />
</div>

The drawbacks

The drawbacks to this solution is that if the user is using a browser that does not support flexbox or IE (where a bug stops the flexbox rules being applied to pseudo elements) the asterisk will be displayed before the label.

Solution 2

A second way to achieve this would be to use absolute positioning. By setting label to position: relative; you can position the :before element at its end by making it position: absolute; and right: 0;. By adding some right padding you can "reserve" space for the element so the text doesn't overlap.

.my-label > label {
  /*10px is for old browsers which don't support the ch unit*/
  padding-right: 10px;
  padding-right: 1ch;
  position: relative;
}
.my-label.required > label:before {
  color: red;
  content: "*";
  position: absolute;
  right: 0;
}
.my-label > label:after {
  content: ":";
}
<div class="my-label">
  <label>Not required</label>
  <input type="text" />
</div>
<div class="my-label required">
  <label>Required</label>
  <input type="text" />
</div>

The drawbacks

Not many drawbacks to this method as it should work in the majority of browsers (even older ones).



回答2:

As said in comments why you don't just add the : to the label itself, since it belongs to content?

Then you can have a simple ::after with the color:red

Why complicate, when the things are simple.

.required::after {
  color: red;
  content: "*";
}
<div>
  <label>Not required:</label>
  <input type="text" />
  <label class="required">Required:</label>
  <input type="text" />
</div>



回答3:

Using the markup suggested by Hidden Hobbes, as an alternative to flexbox, you can use a combination of relative and absolute positioning to place the asterisk in the desired location.

This approach may require some adjustment to get the horizontal and vertical placement just right for the font in use.

.my-label > label {
  display: inline-block;
  position: relative;
}
.my-label.required > label {
  padding-right: 1em;
}
.my-label.required > label:before {
  color: red;
  content: "*";
  position: absolute;
  top: 0.1em;
  right: 0.25em;
}
.my-label > label:after {
  content: ":";
}
<div class="my-label">
  <label>Not required</label>
  <input type="text" />
</div>
<div class="my-label required">
  <label>Required</label>
  <input type="text" />
</div>