First of all, I know there are a lot of questions with this title and I went through them.
Here is my case and what I tried. I have some divs with dinamically added content. What I want is to place the status on the middle of the dotted border. My problem is that if the content of let's say first div has two lines, then my status won't be on the middle of the dotted line.
How cand I make the status always stay in the middle of the dotted line regardless of other content?
EDIT: This is the mobile view of the component, on the desktop view the status should stay on the bottom right side of the container.
.container {
width: 500px;
border: 1px solid black;
position: relative
}
.border {
border-bottom: 1px dashed black;
margin-left: 0px;
margin-right: 0px;
position: relative;
margin-top: 20px;
margin-bottom: 20px;
border-left: 0px;
}
.status {
height: 32px;
line-height: 32px;
border-radius: 7px;
text-align: center;
padding: 0px 10px;
width: -moz-fit-content;
width: fit-content;
font-size: 13px;
font-weight: bold;
color: red;
background-color: pink;
position: absolute;
top: 60%;
left: 50%;
transform: translate(-60%, -50%);
}
.status-wrapper {
margin-top: 0;
}
.text {
padding: 10px;
}
<div >
<div >some text </div>
<div >some other text</div>
<div ></div>
<div >more text</div>
<div >
<div >my status</div>
</div>
</div>
CodePudding user response:
Just wrap border
and status
in a container and set it to relative.
.container {
width: 500px;
border: 1px solid black;
position: relative
}
.border-container {
position: relative;
}
.border {
border-bottom: 1px dashed black;
margin-left: 0px;
margin-right: 0px;
position: relative;
margin-top: 20px;
margin-bottom: 20px;
border-left: 0px;
}
.status {
z-index: 2;
height: 32px;
line-height: 32px;
border-radius: 7px;
text-align: center;
padding: 0px 10px;
width: -moz-fit-content;
width: fit-content;
font-size: 13px;
font-weight: bold;
color: red;
background-color: pink;
position: absolute;
top: 60%;
left: 50%;
transform: translate(-60%, -50%);
}
.status-wrapper {
margin-top: 0;
}
.text {
padding: 10px;
}
<div >
<div >some text </div>
<div >some other text</div>
<div >some more other text</div>
<div >some more more other text</div>
<div >
<div >
<div >my status</div>
</div>
<div ></div>
</div>
<div >more text</div>
</div>
CodePudding user response:
Can't you just put the status inside the border element? Like this:
.container {
width: 500px;
border: 1px solid black;
position: relative
}
.border {
border-bottom: 1px dashed black;
margin-left: 0px;
margin-right: 0px;
position: relative;
margin-top: 20px;
margin-bottom: 20px;
border-left: 0px;
}
.status {
height: 32px;
line-height: 32px;
border-radius: 7px;
text-align: center;
padding: 0px 10px;
width: -moz-fit-content;
width: fit-content;
font-size: 13px;
font-weight: bold;
color: red;
background-color: pink;
position: absolute;
top: 60%;
left: 50%;
transform: translate(-60%, -50%);
}
.status-wrapper {
margin-top: 0;
}
.text {
padding: 10px;
}
<div >
<div >some text </div>
<div >some other text</div>
<div >
<div >
<div >my status</div>
</div>
</div>
<div >more text</div>
</div>
CodePudding user response:
One possible solution is to use display: grid
and position the .status-wrapper
(along with its child) in the same grid-row
as the .border
element:
/* using CSS custom properties to allow for easier
theming and future maintenance: */
:root {
--color-accent: hsl(0 100% 50% / 1);
--color-accent-90: hsl(0 100% 90% / 50);
--color-primary: hsl(0 0% 0% / 1);
--status-block-size: 32px;
--white: hsl(0 100% 100% / 0.9);
}
.container {
/* using the CSS keyword 'currentColor' to assign the
value of the current color property (assigned or
inherited) as the border-color: */
border: 1px solid currentColor;
/* assigning a custom-property as the color property-
value, using the var() function: */
color: var(--color-primary);
/* using CSS grid for layout: */
display: grid;
/* specifying one column taking all available space: */
grid-template-columns: 1fr;
/* using CSS logical properties in place of 'width' */
inline-size: 500px;
}
.border {
/* again, a CSS logical property; in this instance the
block-dimension (size along the block-axis) is set
to 100%; in the English language the inline-axis is
left-to-right, and the block-axis is top-to-bottom: */
block-size: 100%;
/* using repeating-linear-gradient() to create the dashed
"border" effect: */
background-image: repeating-linear-gradient(90deg, currentColor 0 5px, transparent 5px 10px);
/* positioning that imgage at 0 on the inline-axis and 50%
on the block-axis: */
background-position: 0 50%;
/* preventing repeats: */
background-repeat: no-repeat;
/* sizing the image to take 100% of the inline-axis
and 1px on the block-axis (for a 1px 'thick'
'border': */
background-size: 100% 1px;
/* in English, equivalent to 'width': */
inline-size: 100%;
}
.text {
padding: 10px;
}
.status-wrapper {
/* reducing the inline-size of the element to the size
required to show the content of the element: */
inline-size: fit-content;
/* centering the element on the inline-axis: */
justify-self: center;
}
.status {
/* again, CSS custom properties for easy theming: */
background-color: var(--color-accent-90);
/* setting the border-radius according to the
font-szie: */
border-radius: 0.2em;
color: var(--color-accent);
justify-self: center;
/* using an outline to create a visual separation
between the 'status' and the 'border': */
outline: 0.3em solid var(--white);
padding-inline: 10px;
}
.border,
.status-wrapper {
/* centering the elements on the cross-axis; the
grid is set to columns (block-axis) but the
content within is still flowing on the
inline-axis; so align-self is - as 'cross-axis'
might suggest - centering vertically (in Enlish
language websites): */
align-self: center;
/* placing both the .border and .status-wrapper
(and any descendants) in:
grid-row: 3
grid-column: 1
using grid-area shorthand: */
grid-area: 3 / 1;
/* centering on the inline-axis within the grid-area: */
justify-self: center;
}
<div >
<div >some text </div>
<div >some other text</div>
<div ></div>
<div >more text</div>
<div >
<div >my status</div>
</div>
</div>
I like the above solution for its relative simplicity, but dislike it because we're hard-coding the grid-area
in which to position both the .border
and .status-wrapper
. I would much prefer to have the position of the .status-wrapper
dynamically allocated to match the 'natural' position of the .border
element.
Unfortunately, as yet, I've been unable to find a way to allow for that dynamic behaviour.
References:
align-self
.background-image
.background-position
.background-repeat
.background-size
.block-size
.border
.border-radius
.color
.- CSS custom properties:
--*
. - CSS logical properties.
display
.grid-area
.grid-column
.grid-row
.inline-size
.justify-self
.outline
.padding
.padding-inline
.repeating-linear-gradient()
.var()
.