Flexbox overlapping absoluted positioned childrens - css

I got a problem with flexbox containers with absolute positioned childrens.
FIDDLE; if the window getting smaller (in width) the titles getting smaller, what is absolutly correct, the problem is in the digits that are overlapping over the other watches. I tested a bit around with z-Index, background-color but doesn't get anything work.
HTML:
<div class="stopwatch">
<div class="stopwatch__panel">
<div class="stopwatch__header">
<div class="stopwatch__title">Random Title 404531</div>
</div>
<div class="stopwatch__body">
<div class="stopwatch__counter">
<div class="stopwatch__segment stopwatch__segment--five">
<div class="stopwatch__segmentTopLeft"></div>
<div class="stopwatch__segmentTop"></div>
<div class="stopwatch__segmentTopRight"></div>
<div class="stopwatch__segmentMiddle">
<div class="stopwatch__segmentMiddleTop"></div>
<div class="stopwatch__segmentMiddleBottom"></div>
</div>
<div class="stopwatch__segmentBottomLeft"></div>
<div class="stopwatch__segmentBottom"></div>
<div class="stopwatch__segmentBottomRight"></div>
</div>
<div class="stopwatch__segment stopwatch__segment--five">
<div class="stopwatch__segmentTopLeft"></div>
<div class="stopwatch__segmentTop"></div>
<div class="stopwatch__segmentTopRight"></div>
<div class="stopwatch__segmentMiddle">
<div class="stopwatch__segmentMiddleTop"></div>
<div class="stopwatch__segmentMiddleBottom"></div>
</div>
<div class="stopwatch__segmentBottomLeft"></div>
<div class="stopwatch__segmentBottom"></div>
<div class="stopwatch__segmentBottomRight"></div>
</div>
</div>
</div>
</div>
<div class="stopwatch__panel">
<div class="stopwatch__header">
<div class="stopwatch__title">Random Title 714895</div>
</div>
<div class="stopwatch__body">
<div class="stopwatch__counter">
<div class="stopwatch__segment stopwatch__segment--nine">
<div class="stopwatch__segmentTopLeft"></div>
<div class="stopwatch__segmentTop"></div>
<div class="stopwatch__segmentTopRight"></div>
<div class="stopwatch__segmentMiddle">
<div class="stopwatch__segmentMiddleTop"></div>
<div class="stopwatch__segmentMiddleBottom"></div>
</div>
<div class="stopwatch__segmentBottomLeft"></div>
<div class="stopwatch__segmentBottom"></div>
<div class="stopwatch__segmentBottomRight"></div>
</div>
</div>
</div>
</div>
</div>
CSS:
.stopwatch {
position: fixed;
right: 0;
bottom: 0;
display: flex;
justify-content: flex-end;
align-items: flex-end;
max-width: 100%;
width: 100%;
}
.stopwatch__panel {
background-color: #ffffff;
border: 1px solid #dddddd;
display: flex;
flex-flow: column;
min-width: 0;
}
.stopwatch__header {
background-color: #f5f5f5;
display: flex;
align-items: center;
order: 1;
}
.stopwatch__title {
flex: 1 1 auto;
padding: 5px;
border-left: 1px solid #dddddd;
word-wrap: break-word;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.stopwatch__body {
display: flex;
align-items: stretch;
}
.stopwatch__counter {
background-color: #333333;
padding: 15px;
flex-grow: 1;
text-align: center;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
}
.stopwatch__segment {
position: relative;
float: left;
margin: 6px;
width: 18px;
height: 35px;
transition: all 200ms ease-in-out;
}
.stopwatch__segment--zero .stopwatch__segmentTopRight {
border-right-color: #e6e6e6;
}
/* [...all numbers from zero to nine... (only coloring borders) ] */
.stopwatch__segment--nine .stopwatch__segmentBottom {
border-bottom-color: #e6e6e6;
}
.stopwatch__segmentTop {
position: absolute;
left: 1px;
height: 0;
width: 10px;
border-top: 3px solid #424242;
border-left: 3px solid transparent;
border-right: 3px solid transparent;
transition: all 200ms ease-in-out;
}
.stopwatch__segmentTopRight {
position: absolute;
left: 15px;
top: 1px;
height: 10px;
width: 0;
border-right: 3px solid #424242;
border-top: 3px solid transparent;
border-bottom: 3px solid transparent;
transition: all 200ms ease-in-out;
}
/* [... the other segments parts ...] */

add overflow:hidden; to .stopwatch__counter
.stopwatch__counter {
background-color: #333333;
padding: 15px;
flex-grow: 1;
text-align: center;
color: #ffffff;
display: flex;
overflow:hidden;
align-items: center;
justify-content: center; }
see this fiddle:
https://jsfiddle.net/grassog/jcgyce3g/2/

Related

Element does not expand to fill parent flex div

html,
body {
margin: 0;
height: 100%;
}
.navbar {
position: fixed;
top: 0;
width: 100%;
height: 50px;
background-color: #2D4256;
}
.nav-centre {
margin: 0 auto;
width: 40%;
height: 100%;
}
.nav-container {
display: flex;
height: 100%;
align-items: center;
/* vertically centre */
}
.nav-item {
color: white;
width: 40px;
text-align: center;
}
.main-content {
height: calc(100% - 50px);
width: 100%;
position: absolute;
bottom: 0;
overflow-y: overlay;
display: flex;
justify-content: center;
}
.main-wrap {
width: 40%;
border-left: 1px solid black;
border-right: 1px solid black;
}
.box {
width: 200px;
height: 200px;
background: white;
border: 1px solid black;
margin: 10px;
}
<body>
<div class="navbar">
<div class="nav-centre">
<div class="nav-container">
<div class="nav-item">1</div>
<div class="nav-item">2</div>
<div class="nav-item">3</div>
<div class="nav-item">4</div>
</div>
</div>
</div>
<div class="main-content">
<div class="main-wrap">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</body>
The main-wrap div is not expanding to fill the parent main-content div, how can I get the main-wrap element to expand to the full height of the parent?
https://codepen.io/woooof/pen/VwBLprj
The .main-wrapper is getting by default display:block, which doesn't match with the display:flex parent.
To get the value from the parent, you can use display: inherit. Once done, the elements inside won't respect their width. To fix that, you must wrap the elements, and for making it total height, You can use max-content.
.main-wrapper {
display: inherit;
flex-wrap: wrap;
height: max-content;
}
Result:
html,
body {
margin: 0;
height: 100%;
}
.navbar {
position: fixed;
top: 0;
width: 100%;
height: 50px;
background-color: #2D4256;
}
.nav-centre {
margin: 0 auto;
width: 40%;
height: 100%;
}
.nav-container {
display: flex;
height: 100%;
align-items: center;
/* vertically centre */
}
.nav-item {
color: white;
width: 40px;
text-align: center;
}
.main-content {
height: calc(100% - 50px);
width: 100%;
position: absolute;
bottom: 0;
overflow-y: overlay;
display: flex;
justify-content: center;
}
.main-wrap {
width: 40%;
border-left: 1px solid black;
border-right: 1px solid black;
display: inherit;
flex-wrap: wrap;
height: max-content;
}
.box {
width: 200px;
height: 200px;
background: white;
border: 1px solid black;
margin: 10px;
}
<body>
<div class="navbar">
<div class="nav-centre">
<div class="nav-container">
<div class="nav-item">1</div>
<div class="nav-item">2</div>
<div class="nav-item">3</div>
<div class="nav-item">4</div>
</div>
</div>
</div>
<div class="main-content">
<div class="main-wrap">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</body>
I am not a huge fan of making the size of one element (navbar) determine the position of the second element main-content (margin-top). where you have height: calc(100% - 50px); I would rather if the style of the first changes. Say for example we increase navbar font size, you would not need to adjust the second manually.
Here in this example I set the font-size on an ancestor block to change the nav buttons size and not have to change the content. font-size: 1.5rem;
Change it even larger; again no change to the content CSS;
I put a lot of comments in and some borders just to show where things line - that can and should all be removed for a production version.
html,
body {
margin: 0;
height: 100%;
/* stack the nav and the content blocks */
display: grid;
grid-template-rows: 1fr auto;
}
.navbar {
/* put the navbar at the top */
position: sticky;
top: 0;
background-color: #2D4256;
/* flex, default vertical/horizontal centers nav-centre in the flex */
display: flex;
}
.nav-centre {
margin: 0 auto;
display: flex;
}
.nav-container {
display: flex;
/* again these are the default here
flex-direction: row;
align-items: center;
justify-content: center;
*/
/* how much space above and below the yellow border nav container */
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.nav-item {
color: white;
/* 2 times font-size for cyan border items */
width: 2em;
text-align: center;
}
.main-content {
display: grid;
justify-content: center;
}
.main-wrap {
border-left: 1px solid black;
border-right: 1px solid black;
}
.box {
width: 200px;
height: 200px;
background: white;
border: 1px solid black;
margin: 10px;
}
/* below here is just for visual clarification and can be removed */
.navbar {
/* just to show you can style and not effect content block *
/* this can be on any of the three containers */
font-size: 1.5rem;
font-family: Verdana, Arial, Helvetica, sans-serif;
}
.nav-centre {
border: 1px solid magenta;
padding: 2px;
}
.nav-container {
border: 1px solid yellow;
}
.nav-item {
border: 1px solid cyan;
/* you can space out the nav buttons */
margin: 0 0.25rem;
}
.main-content {
/* just to show it is below the navbar and separate */
border: solid red 1px;
margin-top: 0.25rem;
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.box {
background-color: #ffffdd;
}
<body>
<div class="navbar">
<div class="nav-centre">
<div class="nav-container">
<div class="nav-item">1</div>
<div class="nav-item">2</div>
<div class="nav-item">3</div>
<div class="nav-item">4</div>
</div>
</div>
</div>
<div class="main-content">
<div class="main-wrap">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</body>

Is there a way to dynamically change padding of child element to fill parent element?

I need the child element to behave on hover as that the red border (of child element) should be on the same line as the blue one (parent element) from top, left, bottom and right side. Can I do that by padding? There are several boxes with the same structure but different width and height, and with the different length of text (some of them are on two or three lines).
If it is impossible to do it via padding, how can I achieve the same effect via another method?
The code is here
* {
box-sizing: border-box;
}
.out {
display: -webkit-box;
display: flex;
-webkit-box-pack: center;
justify-content: center;
width: 200px;
height: 200px;
margin: 2rem auto;
border: 1px solid blue;
}
.out .in {
font-size: 20px;
line-height: 1;
display: inline-block;
text-align: center;
border: 1px solid red;
padding: 20px;
margin: auto;
transition: padding .7s;
}
.out:hover .in {
padding-top: 90px;
padding-bottom: 90px;
padding-left: 40px;
padding-right: 40px;
background: rgba(0,0,0,.2);
}
<div class="out">
<p class="in">
Hello Friend
</p>
</div>
<div class="out">
<p class="in">
Hello Friend
</p>
</div>
<div class="out">
<p class="in">
Hello Friend this is a new text
</p>
</div>
<div class="out">
<p class="in">
Hello
</p>
</div>
Thanks
If you can add an extra wrapper you can achieve this by nesting flexbox container and by animating flex-grow
* {
box-sizing: border-box;
}
.out {
display: flex;
flex-direction: column;
width: 200px;
height: 200px;
margin: 2rem auto;
justify-content: center;
border: 1px solid blue;
}
.out > div {
display: flex;
justify-content: center;
}
.out .in {
display: flex;
font-size: 20px;
justify-content: center;
align-items: center;
text-align: center;
border: 1px solid red;
padding: 20px;
margin: 0;
}
.out * {
flex-grow: 0;
transition: flex-grow .5s;
}
.out:hover * {
flex-grow: 1;
}
.out:hover .in {
background: rgba(0, 0, 0, .2);
}
<div class="out">
<div>
<p class="in">
Hello Friend
</p>
</div>
</div>
<div class="out" style="width:auto">
<div>
<p class="in">
Hello Friend
</p>
</div>
</div>
<div class="out" style="height:auto;min-height:300px;">
<div>
<p class="in">
Hello Friend this is a new text
</p>
</div>
</div>
<div class="out">
<div>
<p class="in">
Hello
</p>
</div>
</div>
If you need only background animation and - you can use something like this. Here the element ::after scales separately from with text.
* {
box-sizing: border-box;
}
.out {
display: -webkit-box;
display: inline-flex;
vertical-align: top;
-webkit-box-pack: center;
justify-content: center;
width: 200px;
height: 200px;
margin: 2rem auto;
border: 1px solid blue;
overflow: hidden; /* to hide parent exapnded background */
}
.out .in {
font-size: 20px;
line-height: 1;
display: inline-block;
text-align: center;
padding: 20px;
margin: auto;
position: relative;
}
.out .in::after {
content: '';
background: rgba(0,0,0,.2);
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
transform: scale(1);
transition: all .7s;
}
.out:hover .in::after {
transform: scale(5);
}
<div class="out">
<p class="in">
Hello Friend
</p>
</div>
<div class="out">
<p class="in">
Hello Friend this is a new text
</p>
</div>
<div class="out">
<p class="in">
Hello
</p>
</div>
You can add height and width of child 100% on parent hover.
* {
box-sizing: border-box;
}
.out {
display: -webkit-box;
display: flex;
-webkit-box-pack: center;
justify-content: center;
width: 200px;
height: 200px;
margin: 2rem auto;
border: 1px solid blue;
}
.out .in {
font-size: 20px;
line-height: 1;
display: inline-block;
text-align: center;
border: 1px solid red;
padding: 20px;
margin: auto;
transition: padding .7s;
}
.out:hover .in {
padding-top: 90px;
padding-bottom: 90px;
padding-left: 40px;
padding-right: 40px;
background: rgba(0,0,0,.2);
width: 100%;
height: 100%;
}
<div class="out">
<p class="in">
Hello Friend
</p>
</div>
<div class="out">
<p class="in">
Hello Friend
</p>
</div>
<div class="out">
<p class="in">
Hello Friend this is a new text
</p>
</div>
<div class="out">
<p class="in">
Hello
</p>
</div>

How to maintain a circlur shape of element with dynamic content?

I'm trying to create a circle as an ::after pseudo element, which resizes automatically depending on its content.
.container {
display: flex;
flex-direction: row;
}
#dividerHost2 #left {
flex: 1 1 auto;
background-color: yellowgreen;
height: 200px;
}
#dividerHost2 #right {
flex: 1 1 auto;
background-color: dodgerblue;
}
#dividerHost2 .divider {
background-color: white;
margin: 0px;
width: 6px;
font-weight: 800;
}
.divider.vertical {
--divider-color: transparent;
display: inline-flex;
width: 1px;
border-left: 1px solid rgb(var(--divider-color));
margin: 0px 2px 0px 2px;
overflow: show;
}
.divider.vertical.title::after {
flex: 0 0 auto;
align-self: center;
border-radius: 50%;
content: "OR";
padding: 9px 8px 11px 8px;
background-color: white;
color: black;
transform: translateX(-44%);
z-index: 10;
}
<div id="dividerHost2" class="container">
<div id="left" class="container" style="flex-direction: row;"></div>
<div id="divider3" class="divider vertical title"></div>
<div id="right" class="container" style="flex-direction: row;"></div>
</div>
That gives a pretty nice result so far:
JSFiddle https://jsfiddle.net/jsnbtmh3/
However, with longer text the circle turns into an oval:
How to make the circle auto resize depending on its content?
Here is a trick using radial-gradient. The idea is to keep the element full height and color it using circle closest-side which will always create a circle that will start from the center and expand to the closest sides (left and right one)
I simplified the code to keep only the relevant part:
.container {
display: flex;
flex-direction: row;
margin:10px;
}
.left {
flex: 1 1 auto;
background-color: yellowgreen;
height: 200px;
}
.right {
flex: 1 1 auto;
background-color: dodgerblue;
}
.divider {
background-color: white;
width: 6px;
font-weight: 800;
display: flex;
justify-content: center;
}
.divider::after {
display: flex;
align-items: center;
flex: 0 0 auto;
content: attr(data-text);
padding: 0 8px;
background: radial-gradient(circle closest-side, white 98%, transparent 100%);
z-index: 10;
}
<div class="container">
<div class="left "></div>
<div class="divider" data-text="OR"></div>
<div class="right "></div>
</div>
<div class="container">
<div class="left "></div>
<div class="divider" data-text="longer"></div>
<div class="right "></div>
</div>
<div class="container">
<div class="left "></div>
<div class="divider" data-text="even longer"></div>
<div class="right "></div>
</div>
Don't put actual content in the pseudo-element especially as this is actually "content" rather than styling, rather use the pseudo-element to create a background circle using the padding/aspect ratio trick.
body {
text-align: center;
}
.divider {
margin: 3em;
display: inline-block;
position: relative;
padding: 1em;
font-weight: bold;
}
.divider:after {
content: "";
position: absolute;
width: 100%;
padding-top: 100%;
background: lightblue;
border-radius: 50%;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: -1;
}
<div class="divider">OR</div>
<div class="divider">LONG TEXT</div>

Css solution for circle and line

I am looking for a css solution to the below image that is responsive.
I have the following html and css, but it isn't respnosive and I need the line to float alongside the circle.
<div class="col-xs-6 col-sm-2">
<div class="circle"> </div>
<div class="line"><img src="assets/line.png" class="black-line"></div>
</div>
.circle {
background-color:#fff;
border:2px solid #222;
height:50px;
border-radius:50%;
-moz-border-radius:50%;
-webkit-border-radius:50%;
width:50px;
float: left;
line-height: 50px;}
.line { line-height: 50px; text-align: center; float: left; padding: 0 8px;}
Here's a working responsive version of this:
.container {
border-bottom: 3px solid #111;
height: 1rem;
display: flex;
justify-content: space-between;
}
.circle {
display: inline-block;
background: #fff;
width: 2rem;
height: 2rem;
border: 2px solid #111;
border-radius: 2.5rem;
box-shadow: 0 0 0 0.5rem #fff;
}
#media (min-width: 768px) {
.container {
height: 2.5rem;
}
.circle {
width: 5rem;
height: 5rem;
}
}
<div class="container">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
Elements of this might not suit your needs, although with the information provided it's difficult to say. However, it should provide a solid starting point.
Here's my attempt on a responsive approach with flexbox. The crossing line has been done using a pseudoelement (no need to use markup for styling purpose)
The gap between a circle and the line has been done with the box-shadow property
<div class="circlesbox">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
CSS
.circlesbox {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
}
.circlesbox:before {
content: "";
position: absolute;
zindex: 1;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 3px;
width: 100%;
background: #000;
}
.circle {
position: relative;
z-index: 2;
border: 2px solid #222;
background: #fff;
box-shadow: 0 0 0 20px #fff;
width:50px;
height:50px;
border-radius:50%;
}
Final result

Css Circle and text inline

Hello i need to have a css circle and on right a text, inline.
I use this code
<div class="circlearancione">Disponibile</div>
.circlearancione{
background-color: red;
border-color: white;
border-radius: 50%;
border-width: 5px;
height: 25px;
width: 25px;
}
But using this my text not have any space between circle and text. I try to use margin and padding but nothing change.
Also try to use
<div class="circlearancione"></div><p>Disponibile</p>
.circlearancione, p { display: inline; }
But with this not display the circle.
What's wrong?
Thanks
You can use :before pseudo-element for circle and Flexbox for vertical alignment.
.circlearancione {
display: flex;
align-items: center;
}
div:before {
content: '';
background-color: red;
border-color: white;
border-radius: 50%;
border-width: 5px;
height: 25px;
width: 25px;
}
<div class="circlearancione">Disponibile</div>
You can also put your text in span and add it some margin-left.
.circlearancione {
background-color: red;
border-color: white;
border-radius: 50%;
border-width: 5px;
height: 25px;
width: 25px;
line-height: 25px;
}
span {
margin-left: 30px;
}
<div class="circlearancione"><span>Disponibile</span></div>
You could use simple flex to achieve it. It promotes fluid, responsive, scalable and readable structure.
HTML
<div class="container">
<div class="circlearancione"></div>
<p>Disponibile1</p>
</div>
<div class="container">
<div class="circlearancione"></div>
<p>Disponibile2</p>
</div>
<div class="container">
<div class="circlearancione"></div>
<p>Disponibile3</p>
</div>
CSS
.container {
display: flex;
align-items: center;
justify-content: center;
}
p { margin:0; }
.container {
display: flex;
align-items: center;
justify-content: center;
}
.circlearancione{
background-color: red;
border-color: white;
border-radius: 50%;
border-width: 5px;
height: 25px;
width: 25px;
}
p { margin:0; }
<div class="container">
<div class="circlearancione"></div>
<p>Disponibile1</p>
</div>
<div class="container">
<div class="circlearancione"></div>
<p>Disponibile2</p>
</div>
<div class="container">
<div class="circlearancione"></div>
<p>Disponibile3</p>
</div>
I can imagine something like this if you would like to avoid using flex.
.circlearancione {
display: inline-block;
vertical-align: middle;
margin: 0 5px 0 0;
background-color: red;
border-color: white;
border-radius: 50%;
border-width: 5px;
height: 25px;
width: 25px;
}
<div id="container">
<p>
<span class="circlearancione"></span>Disponibile
</p>
</div>
My suggestion would be to place a span within your div that will act like the circle
<div class="circlearancione"><span></span> Disponibile</div>
Here is a fiddle: https://jsfiddle.net/v5LLp7uf/

Resources