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

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>

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>

How to best make curved edges of Divs outside of the functionality of border-radius? [duplicate]

This question already has an answer here:
How to create uneven rounded sides on a div?
(1 answer)
Closed 10 months ago.
I'm trying to create a web element like this, but am having trouble figuring out how to make a curved border between two divs. I understand the functionality of border-radius (very bad implementation in codepen below), bit wanted to see if anyone had ideas on how to implement the picture above? I thought about having a border-radius with a much larger radius, then hiding overflow, but not sure if that makes sense.
https://codepen.io/unsure-of-name/pen/LYeBdbX
.circle {
height: 100px;
width: 100px;
background-color: #eee;
border-radius: 100px;
box-shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.2), 0 0px 20px 0 rgba(0, 0, 0, 0.19);
display: inline-block;
vertical-align: top;
position: relative;
z-index: 2;
}
.bar {
display: inline-block;
margin-top: 25px;
background-color: #eee;
margin-left: -50px;
padding-left: 50px;
height: 50px;
text-align: center;
positive: relative;
z-index: 1;
}
.bar div:nth-child(1) {
background-color: red;
border-radius: 10px;
}
.bar div:nth-child(2) {
background-color: #bbb;
}
.bar div:nth-child(3),
.bar div:nth-child(4) {
background-color: #eee;
border-right: 1px solid black;
}
.bar div {
display: inline-block;
vertical-align: middle;
text-align: center;
line-height: 50px;
}
.row {
}
.row > div {
}
<div class='container'>
<div class='row'>
<div class='circle'>
</div>
<div class='bar'>
<div>
Group 1
</div>
<div>
Description
</div>
<div>
Cell 1
</div>
<div>
Cell 2
</div>
</div>
</div>
<div class='row'>
<div class='circle'>
</div>
<div class='bar'>
<div>
Group 1
</div>
<div>
Description
</div>
<div>
Cell 1
</div>
<div>
Cell 2
</div>
</div>
</div>
</div>
Thanks!
That's some very confusing css you have written. The css below will get you what you want. You still have to organize the rest of it. Hope this helps.
.row{
display: flex;
align-items: center;
}
.bar {
display: inline-block;
background-color: #eee;
margin-left: -50px;
padding-left: 50px;
height: 50px;
display: flex;
text-align: center;
positive: relative;
z-index: 1;
}
.bar div{
padding: 0 10px;
width: 100px;
}
.bar div:nth-child(1) {
position: relative;
background: red;
color: black;
height: 50px;
}
.bar div:nth-child(1)::before{
content: '';
width: 20px;
height: 100%;
position: absolute;
bottom: 0;
right: -5px;
background: red;
border-radius: 100%;
}
You can try using ellipse to define the how 'curvy' the side should look
#box1 {
background: red;
width: 10rem;
height: 3rem;
padding: 0.5rem;
clip-path: ellipse(10rem 7.5rem at left);
}
.wrapper {
background: blue;
width: 20rem;
}
<div class="wrapper">
<div id="box1">
</div>
</div>

How can we shrink middle flex item?

I am trying to make a layout from flexbox. I have 3 column of boxes which have following layout till they reach mobile layout where they will stack on top of another.
But before I reach mobile layout I am trying to shrink all the items proportionally. (i.e when I reduce the browsers width, it should equally be small). But only the left and right items are equally reducing except the middle item. How do I make that shrink so that all the items proportionally shrink while reducing browsers width?
CODE GOES HERE
.container {
width: 100%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding-top: 80px;
}
.box {
width: 400px;
/* min-width: 280px; */
height: 400px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid black;
font-size: 30px;
font-weight: bold;
font-family: cursive;
box-shadow: 1px 4px 3px rgba(0, 0, 0, 0.5);
}
.box1 {
background: grey;
}
.box2 {
background: green;
margin-bottom: 20px;
}
.box3 {
background: greenyellow;
}
.box4 {
background: orange;
}
.middle-part {
margin: 0px 20px;
/* min-width: 280px; */
}
<div class="container">
<div class="box box1">
I am box1
</div>
<div class="middle-part">
<div class="box box2">
I am box2
</div>
<div class="box box3">
I am box3
</div>
</div>
<div class="box box4">
I am box4
</div>
</div>
If you want it to shrink dynamically, you need to remove the width set. Add flex-grow: 1 on .box and .middle-part to make it grow. In addition, padding-top only accept 1 value, so perhaps some typos there.
.container {
width: 100%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding-top: 80px 40px; /* padding top only accept 1 value */
}
.middle-part {
flex-grow: 1;
}
.box {
flex-grow: 1;
/* min-width: 280px; */
height: 400px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid black;
font-size: 30px;
font-weight: bold;
font-family: cursive;
box-shadow: 1px 4px 3px rgba(0, 0, 0, 0.5);
}
.box1 {
background: grey;
}
.box2 {
background: green;
margin-bottom: 20px;
}
.box3 {
background: greenyellow;
}
.box4 {
background: orange;
}
.middle-part {
margin: 0px 20px;
/* min-width: 280px; */
}
<body>
<div class="container">
<div class="box box1">
I am box1
</div>
<div class="middle-part">
<div class="box box2">
I am box2
</div>
<div class="box box3">
I am box3
</div>
</div>
<div class="box box4">
I am box4
</div>
</div>
</body>

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