css 如何在输入底部边框的末尾创建一个点

mtb9vblg  于 2023-05-08  发布在  其他
关注(0)|答案(4)|浏览(167)

我想通过在输入的末尾添加一个点来设置输入的样式。与下图相同

我试着为:before:after添加一些样式,但我无法弄清楚

.parent {
  max-width: 352px;
  width: 100%;
}

.children {
  display: flex;
  align-items: center;
  width: 100%;
  margin: 10px 0;
}

.line {
  width: 100%;
  height: 1px;
  background-color: red;
}

.the-dot {
  width: 1px;
  height: 1px;
  background-color: red;
  border-radius: 999px;
}

.children input {
  border: none;
  border-bottom: 1px solid;
  margin-right: 5px;
  flex-grow: 1;
}
<div class="parent">
  <div class="children">
    <input type="text" placeholder="Type something...">
    <div class="line"></div>
    <div class="the-dot"></div>
  </div>
</div>
x8goxv8g

x8goxv8g1#

您可能不需要使用flex-container进行设置,相反,我们可以使用position: relative为点元素创建一个锚,在我的示例中,它将是一个伪元素。我的解决方案就是基于这个假设。
对于红点的位置,我们可以用途:

position: absolute;
right: 0;
bottom: 0;

这将把它放在右下角。
接下来,我使用以下命令将元素居中:

transform: translate(50%, 50%);

考虑到元素比例,元素将被放置在正中间。然而,从视觉上看,输入的底线看起来差了一个像素,我们可以手动调整点从bottom: 1px开始。

* {
  box-sizing: border-box;
}

.parent {
  max-width: 352px;
  width: 100%;
}

.input-with-dot {
  position: relative;
  width: 100%;
  margin: 10px 0;
}

.input-with-dot::after {
  content: " ";
  position: absolute;
  right: 0;
  /* visual adjustment, because of the line-size of 1px */
  bottom: 1px;
  transform: translate(50%, 50%);
  width: 10px;
  height: 10px;
  background-color: red;
  border-radius: 50%;
}

.input-with-dot input {
  width: 100%;
  border: none;
  border-bottom: 1px solid;
}
<div class="parent">
  <div class="input-with-dot">
    <input type="text" placeholder="Type something...">
  </div>
</div>
nhaq1z21

nhaq1z212#

在没有使用flex和将点嵌套在行内的情况下,我最终得到了这样的结果:

.parent {
  max-width: 352px;
  width: 100%;
}

.line{
  width: 100%;
  height: 1px;
  background-color: black;
  margin-top:15px;
  display:block;
}

.the-dot {
  width: 8px;
  height: 8px;
  background-color: red;
  border-radius: 50%;
  display:inline-block;
  float:right;
  margin-top:-4px;
  }

input {
  width:100%;
  display:block;
  border: none;
  border-bottom: 1px solid;
  outline:0;
  border:0;
}
<div class="parent">
    <input type="text" placeholder="Type something...">
    <div class="line"><div class="the-dot"></div></div>
</div>
busg9geu

busg9geu3#

只需使用position: absolute来定位使用border-radiusaspect-ratio创建的点:

.children {
  position: relative;
}

.the-dot {
  position: absolute;
  /* 100% of .children's height, minus half its size, minus half line width. */
  top: calc(100% - var(--size) / 2 - var(--border) / 2);
  /* 100% of .children's width, minus half its size. */
  left: calc(100% - var(--size) / 2);
  /* Make it round */
  border-radius: 50%;
  height: var(--size);
  /* Ensure that its height is equal to its width */
  aspect-ratio: 1 / 1;
}

或者,您可以使用伪元素:

.children::after {
  content: '';
  /* idem */
}

试试看:

/* Play with these */
:root {
  --size: 5px;
  --color: #f00;
  --border: 1px;
}

.children {
  position: relative;
}

.the-dot {
  position: absolute;
  top: calc(100% - var(--size) / 2 - var(--border) / 2);
  left: calc(100% - var(--size) / 2);
  border-radius: 50%;
  height: var(--size);
  aspect-ratio: 1 / 1;
  background: var(--color);
}

/* Demo only */

.parent {
  max-width: 352px;
  width: 100%;
}

.children {
  display: flex;
  align-items: center;
  width: 100%;
  margin: 10px 0;
}

.children input {
  border: none;
  border-bottom: var(--border) solid;
  flex-grow: 1;
}
<div class="parent">
  <div class="children">
    <input type="text" placeholder="Type something...">
    <div class="the-dot"></div>
  </div>
</div>
gxwragnw

gxwragnw4#

一种方法如下,在代码中有解释性注解;这种方法有一个可以论证的好处,即通过使用<label>元素来环绕<input>并删除表示元素(.line.dot<div>元素)来帮助可访问性:

/* a simple CSS reset, to ensure that browsers use the
   the same - border-box - sizing algorithm, to include
   padding and borders in the declared element sizes,
   removing default margin and padding and ensuring that
   font properties are inherited from ancestors: */

*,
::before,
::after {
  box-sizing: border-box;
  font: inherit;
  margin: 0;
  padding: 0;
}

body {
  /* specifying that the <body> should take up the full
     size of the viewport on the block axis: */
  block-size: 100vh;
  /* generic font styles for the page, adjust to your preferences: */
  font-family: system-ui;
  font-size: 16px;
  font-weight: 400;
  /* declaring padding on the block, and inline, axes: */
  padding-block: 1rem;
  padding-inline: 1.5rem;
}

.halfSize {
  width: 50%;
}

label {
  /* using flex layout: */
  display: flex;
  font-size: 1.5rem;
  /* shorthand for:
       flex-direction: row;
       flex-wrap: wrap;
  */
  flex-flow: row wrap;
}

label > * {
  /* all children of the <label> element will take
     100% of the available space: */
  flex-basis: 100%;
  /* and will have padding on their block, and inline,
     axes: */
  padding-block: 0.25rem;
  padding-inline: 0.5rem;
}

input {
  /* custom properties for the various details of the
     border we're creating;
     --borderColor is the colour of the border: */
  --borderColor: var(--borderColorStart);
  /* this is the default border-color, based on the
     color of the font; this can be updated in the CSS
     for specific elements or in the HTML "style"
     attribute, for example:
     <input style="--borderColor: lime">:
  */
  --borderColorStart: currentColor;
  /* this property defaults to the --borderColorStart
     value, but if a gradient is desired then you can
     set a different value (either here, or in specific
     rulesets for specific elements, or in the html as
     above): */
  --borderColorEnd: var(--borderColorStart);
  /* effectively acting as 'border-width', this sets the
     thickness of the horizontal gradient/line: */
  --borderSize: 0.25rem;
  /* the desired dot-color: */
  --dotColor: red;
  /* calculating where the dot should be positioned in
     order to be placed at the bottom right; the calculation
     could easily be adjusted to place it at any alternative
     position: */
  --dotPosition: calc(100% - var(--dotRadius));
  /* calculating the radius of the dot, in order to aid
     other calculations: */
  --dotRadius: calc(var(--dotSize) / 2);
  /* the size that the dot should be: */
  --dotSize: 1rem;
  /* using multiple gradients as background images to
     reproduce the line and dot: */
  background-image: radial-gradient(/* a radial gradient is used for the dot, here
         we specify a circle to be used: */
  circle, /* we use the declared --dotColor custom property,
         which extends from 0 to the calculated radius: */
  var(--dotColor) 0 var(--dotRadius), /* we then switch to transparent (to allow for the
         background-color or other background-images to
         show through without clipping) from the --dotRadius
         size extending to the full size of the gradient: */
  transparent var(--dotRadius)), linear-gradient(/* using a linear-gradient to generate the solid 'border',
         this is positioned at 90degrees so that it runs
         horizontally (0deg is vertical): */
  90deg, /* we start with the assigned --borderColorStart color value: */
  var(--borderColorStart), /* and end with the --borderColorEnd value, which defaults
         to the same declared color as --borderColorStart for a
         solid single line-colour, but can be overriden to create
         a smooth gradient: */
  var(--borderColorEnd));
  /* setting the background positions of the images, the first (radial-gradient)
     is positioned at 100% 100% (at the right bottom point), and the second
     (linear-gradient) is positioned at zero (left) and 100% of the
     element's height minus both the size of the --dotRadius and half of the
     --borderSize divided by 2, so half the --dotSize and half the --borderSize: */
  background-position: 100% 100%, 0 calc(100% - (var(--dotRadius) - var(--borderSize)/2));
  /* preventing repeating backgrounds: */
  background-repeat: no-repeat;
  /* setting the size of the background-images, the first (radial-gradient) is sized
     to be the declared --dotSize on both axes (inline and block), whereas the
     linear-gradient is sized to be full-width (100%) minus the --dotSize, and
     its height is the declared --borderSize: */
  background-size: var(--dotSize) var(--dotSize), calc(100% - var(--dotSize)) var(--borderSize);
  /* removing default element borders: */
  border: 0 none transparent;
  /* setting the padding on the block-end (the block-axis is the axis on which
     block-elements are laid out by default, vertical in the English language),
     the block-end position is the last edge of the element on the block-axis;
     this is - in English - equivalent to padding-bottom; there's a calculation
     to create the value, which is three-quarters of the --dotSize; this can -
     and perhaps should be - adjusted to your own preferences:: */
  padding-block-end: calc(var(--dotSize) * 0.75);
}
<div class="parent">
  <label>
    <span class="labelText">Name</span>
    <input type="text" placeholder="Type something...">
  </label>
</div>

<div class="parent halfSize">
  <label>
    <span class="labelText">Name</span>
    <input type="text" placeholder="Type something...">
  </label>
</div>

JS Fiddle demo
顺便说一句,我确信这可以通过使用border-image属性来实现,但我个人对该属性的理解不够好,无法使用它,也不知道我在用它做什么;其他人可能会及时提供这样的解决方案,我热切期待。
参考文献:

相关问题