I am creating some cards that are to display a kind of timeline, and I want to do that by having some card divs with content that are connected with a line and with a circle at each of the ends of the line to make it look good. Currently I just have the cards, and I cannot figure out how to make the connected lines. I currently have something like this:
HTML:
<div class="card-wrapper">
<div class="card">
</div>
<div class="card">
</div>
</div>
CSS:
.card-wrapper {
display: flex;
align-items: center;
align-content: center;
flex-direction: row;
}
.card {
width: 15rem;
height: 25rem;
background-color: #4090ff;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin: 2rem 4rem;
box-shadow: 0.5rem 0.5rem 3rem rgba(0, 0, 0, 0.3);
}
JSFiddle: https://jsfiddle.net/L3h9xe5d/10/
And I want something like this:
Please follow the above steps..
HTML
<div class="card-wrapper">
<div class="card">
<div class="card-inner"></div>
</div>
<div class="card">
<div class="card-inner"></div>
</div>
<div class="card">
<div class="card-inner"></div>
</div>
<div class="card">
<div class="card-inner"></div>
</div>
</div>
css
.card-wrapper {
display: flex;
align-items: center;
align-content: center;
flex-direction: row;
}
.card {
width: 15rem;
height: 25rem;
background-color: #4090ff;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin: 2rem 4rem;
box-shadow: 0.5rem 0.5rem 3rem rgba(0, 0, 0, 0.3);
position: relative;
}
.card::after {
position: absolute;
right: -20px;
top: 50%;
transform: translateY(-50%);
width: 26px;
height: 26px;
background-color: #4090ff;
border-radius: 50%;
border: 6px solid #fff;
content: "";
}
.card::before {
position: absolute;
left: -20px;
top: 50%;
transform: translateY(-50%);
width: 26px;
height: 26px;
background-color: #4090ff;
border-radius: 50%;
border: 6px solid #fff;
content: "";
z-index: 9;
}
.card:first-child::before,
.card:last-child::after,
.card:first-child .card-inner::before,
.card:last-child .card-inner::after {
display: none;
}
.card-inner {
width: 100%;
height: 100%;
}
.card-inner::after {
position: absolute;
right: -65px;
top: 50%;
transform: translateY(-50%);
background-color: #000;
content: "";
width: 65px;
height: 4px;
}
.card-inner::before {
position: absolute;
left: -65px;
top: 50%;
transform: translateY(-50%);
background-color: #000;
content: "";
width: 65px;
height: 4px;
}
Related
What is the best way to create a diagonal line between the space of two concentric circles that will adjust in length depending on the space between the outer and inner circle as I want to be able to change the diameter of the outer and inner circle and have the line adjust dynamically.
This is a simple static version of my code: jsFiddle: https://jsfiddle.net/Kaevonz/mowahL2v/204/
This is the full dynamic version of my code with jQuery: https://jsfiddle.net/Kaevonz/fkbrpL54/46/
This is essentially what I am trying to recreate: I want the wall thickness label to adjust dynamically.
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: start;
height: 500px;
border: 1px solid gray;
}
.elem {
box-sizing: border-box;
}
.div1 {
border-top: 3px solid #0DA8AA;
border-left: 1px solid #0DA8AA;
border-right: 1px solid #0DA8AA;
height: 60px;
width: 150px;
background: white;
}
.div2 {
border: 1px solid #0DA8AA;
border-radius: 50%;
width: 290px;
height: 290px;
background: white;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.div3 {
border: 1px solid #0DA8AA;
border-radius: 50%;
width: 240px;
height: 240px;
background: white;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.div4 {
border-top: 0.5px dashed black;
width: 100%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
}
.div5 {
border: 0.5px dashed black;
width: 150px;
height: 50px;
position: absolute;
top: 0;
transform: translateX(-50%);
left: 50%;
float: left;
}
<div class="container">
<div class="elem div1"></div>
<div class="elem div2">
<div class="elem div3">
<div class="elem div5">
</div>
<div class="elem div4">
</div>
</div>
</div>
</div>
You could add that line by drawing a radius on the larger circle using a pseudo element and covering up the part that is within the smaller circle by giving the smaller circle a higher z index (as it already has a background color set).
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: start;
height: 500px;
border: 1px solid gray;
}
.elem {
box-sizing: border-box;
}
.div1 {
border-top: 3px solid #0DA8AA;
border-left: 1px solid #0DA8AA;
border-right: 1px solid #0DA8AA;
height: 60px;
width: 150px;
background: white;
}
.div2 {
border: 1px solid #0DA8AA;
border-radius: 50%;
width: 290px;
height: 290px;
background: white;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.div2::before {
content: '';
position: absolute;
left: 0;
top: 50% - 0.5px;
width: 50%;
height: 1px;
background: gray;
transform: translateY(-50%) rotate(45deg);
transform-origin: right center;
}
.div3 {
border: 1px solid #0DA8AA;
border-radius: 50%;
width: 240px;
height: 240px;
background: white;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 1;
}
.div4 {
border-top: 0.5px dashed black;
width: 100%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
}
.div5 {
border: 0.5px dashed black;
width: 150px;
height: 50px;
position: absolute;
top: 0;
transform: translateX(-50%);
left: 50%;
float: left;
}
<div class="container">
<div class="elem div1"></div>
<div class="elem div2">
<div class="elem div3">
<div class="elem div5">
</div>
<div class="elem div4">
</div>
</div>
</div>
</div>
I am trying to add text that is aligned with a pseudo-element on a div. For reference, I am talking about the .div2::before in my code as that is the dashed line between the inner and outer circle. I want to add a label that says "Wall Thickness" as shown below. The text should adjust with the circle size as the inner/outer circle size will be increasing/decreasing but the text position should adapt. What is the best way to accomplish this?
jsFiddle: https://jsfiddle.net/Kaevonz/cjpkxg6L/6/
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: start;
height: 500px;
border: 1px solid gray;
}
.elem {
box-sizing: border-box;
}
.div1 {
border-top: 3px solid #0DA8AA;
border-left: 1px solid #0DA8AA;
border-right: 1px solid #0DA8AA;
height: 60px;
width: 150px;
background: white;
}
.div2 {
border: 1px solid #0DA8AA;
border-radius: 50%;
width: 340px;
height: 340px;
background: white;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.div2::before {
content: '';
position: absolute;
left: 0;
top: 50% - 0.5px;
width: 50%;
height: 1px;
border-top: 0.5px dashed black;
transform: translateY(-50%) rotate(45deg);
transform-origin: right center;
}
.div3 {
border: 1px solid #0DA8AA;
border-radius: 50%;
width: 120px;
height: 120px;
background: white;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 1;
}
.div4 {
border-top: 0.5px dashed black;
width: 100%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
}
.div5 {
border: 0.5px dashed black;
width: 150px;
height: 50px;
position: absolute;
top: 0;
transform: translateX(-50%);
left: 50%;
float: left;
}
<div class="container">
<div class="elem div1"></div>
<div class="elem div2">
<div class="elem div3">
<div class="elem div5">
</div>
<div class="elem div4">
</div>
</div>
</div>
</div>
We need two elements within each other. Since we can't do that with pseudo elements, we need to add one element to the markup.
The newly added element will serve as a reference for where the text should be placed, so we align it exactly the same way as we would the first pseudo element.
And finally we use a child element or preferably a pseudo element for the text.
Note: for pseudo elements, text can be added via attributes.
DEMO
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: start;
height: 500px;
border: 1px solid gray;
}
.elem {
box-sizing: border-box;
}
.div1 {
border-top: 3px solid #0DA8AA;
border-left: 1px solid #0DA8AA;
border-right: 1px solid #0DA8AA;
height: 60px;
width: 150px;
background: white;
}
.div2 {
border: 1px solid #0DA8AA;
border-radius: 50%;
width: 340px;
height: 340px;
background: white;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.div2::before {
content: '';
position: absolute;
left: 0;
top: 50% - 0.5px;
width: 50%;
height: 1px;
border-top: 0.5px dashed black;
transform: translateY(-50%) rotate(45deg);
transform-origin: right center;
}
.div3 {
border: 1px solid #0DA8AA;
border-radius: 50%;
width: 120px;
height: 120px;
background: white;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 1;
}
.div4 {
border-top: 0.5px dashed black;
width: 100%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
}
.div5 {
border: 0.5px dashed black;
width: 150px;
height: 50px;
position: absolute;
top: 0;
transform: translateX(-50%);
left: 50%;
float: left;
}
/* NEW */
.text {
height: 1px;
position: absolute;
left: 0;
top: 50%;
width: 50%;
transform: translateY(-50%) rotate(45deg) translateX(-20%);
transform-origin: right center;
}
.text:before {
content: 'WE HAVE TEXT, lots of it';
transform: translateY(-50%) rotate(-135deg);
position: absolute;
right: 100%;
writing-mode: vertical-rl;
height: 100px;
/* height as width */
}
/* Preview */
.div2 {
animation: x 1s linear alternate infinite;
}
#keyframes x {
from {
height: 300px;
width: 300px;
}
to {
height: 450px;
width: 450px;
}
}
<div class="container">
<div class="elem div1"></div>
<div class="elem div2">
<div class="text"></div> <!-- NEW -->
<div class="elem div3">
<div class="elem div5">
</div>
<div class="elem div4">
</div>
</div>
</div>
</div>
I had to do some text alignment magic, which may or may not be optimal, but at this point I believe the idea is passed across.
I need little help, I'm new to JavaScript. I'm not sure how to fix the bug, currently, the code on hover is making the first box to display the title. But I want the title to be shown only on the chosen box. I thought in the for loop, the boxes[i] will make his first className[0] to display flex, but I guess it doesn't work that way. How can I fix this?
var boxes = document.getElementsByClassName("portfolio-content-box");
for(var i = 0; i < boxes.length; i ++){
boxes[i].addEventListener("mouseover", function(){
document.getElementsByClassName("portfolio-content-title-box")[0].style.display = "flex";
})
}
.portfolio-content {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-self: center;
margin-top: 100px;
padding: 2rem;
}
.portfolio-content-box {
position: relative;
width: 400px;
height: 350px;
margin: 1rem;
border-left:2px solid red;
cursor:pointer;
transition:0.3s;
}
.portfolio-content-box:hover {
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
}
.portfolio-content-img {
width: 400px;
height: 350px;
object-fit: cover;
}
.portfolio-content-title-box {
position: absolute;
top:0;
left:0;
color: #FFF;
text-shadow: 0px 1px 1px RGBA(0,0,0,1);
background-color:rgba(0,0,0,0.8);
width:100%;
height:100%;
display:none;
}
.portfolio-content-title {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div id="portfolio-container">
<div class="portfolio-content-box">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRyn7ssQEg-KFcYHmAelMv3ro3wGqsMdmE8lw&usqp=CAU" class="portfolio-content-img"/>
<span class="portfolio-content-title-box">
<span class="portfolio-content-title">Title</span>
</span>
</div>
<div class="portfolio-content-box">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQqg54h1j3ljdf73LUi1rAobP0jxmrbEd9W1A&usqp=CAU" class="portfolio-content-img"/>
<span class="portfolio-content-title-box">
<span class="portfolio-content-title">Title</span>
</span>
</div>
</div>
Not sure why you want to use JS, but it can be done with pure CSS. You just need to target the title box when someone hovers the content box as below
.portfolio-content-box:hover>.portfolio-content-title-box {
display: flex;
}
Working Code
.portfolio-content {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-self: center;
margin-top: 100px;
padding: 2rem;
}
.portfolio-content-box {
position: relative;
width: 400px;
height: 350px;
margin: 1rem;
border-left: 2px solid red;
cursor: pointer;
transition: 0.3s;
}
.portfolio-content-box:hover {
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
}
.portfolio-content-img {
width: 400px;
height: 350px;
object-fit: cover;
}
.portfolio-content-title-box {
position: absolute;
top: 0;
left: 0;
color: #FFF;
text-shadow: 0px 1px 1px RGBA(0, 0, 0, 1);
background-color: rgba(0, 0, 0, 0.8);
width: 100%;
height: 100%;
display: none;
}
.portfolio-content-title {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.portfolio-content-box:hover>.portfolio-content-title-box {
display: flex;
}
<div id="portfolio-container">
<div class="portfolio-content-box">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRyn7ssQEg-KFcYHmAelMv3ro3wGqsMdmE8lw&usqp=CAU" class="portfolio-content-img" />
<span class="portfolio-content-title-box">
<span class="portfolio-content-title">Title</span>
</span>
</div>
<div class="portfolio-content-box">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQqg54h1j3ljdf73LUi1rAobP0jxmrbEd9W1A&usqp=CAU" class="portfolio-content-img" />
<span class="portfolio-content-title-box">
<span class="portfolio-content-title">Title</span>
</span>
</div>
</div>
I would like to layer multiple DIVs on top of one another while using flexbox to vertically and horizontally center them both.
In the example below, I would like both .whitebox and .bluebox to be vertically and horizontally centered inside of the container, overlapping one another. Currently .whitebox is positioned with absolute position. Is this possible?
.container {
height: 16px;
width: 16px;
background-color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
overflow: hidden;
position: relative;
}
.bluebox {
height: 16px;
width: 16px;
background-color: #0073FF;
border-radius: 4px;
position: absolute;
top: 0;
left: 0;
}
.whitebox {
height: 8px;
width: 8px;
background-color: white;
border-radius: 4px;
position: absolute;
top: 0;
left: 0;
}
<div class="container">
<div class="bluebox"></div>
<div class="whitebox"></div>
</div>
No need to position the top and left. Just applying absolute positioning is enough because that "pops" the elements into their own layers, so they can be placed at will without affecting other elements in that layer. Once you do that, the align-items and justify-content will do their jobs.
.container {
height: 16px;
width: 16px;
background-color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
overflow: hidden;
position: relative;
}
.bluebox {
height: 16px;
width: 16px;
background-color: #0073FF;
border-radius: 4px;
position: absolute;
}
.whitebox {
height: 8px;
width: 8px;
background-color: white;
border-radius: 4px;
position: absolute;
}
.border {
height: 16px;
width: 16px;
border-radius: 4px;
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1);
position: absolute;
top: 0;
left: 0;
}
<div class="container">
<div class="bluebox"></div>
<div class="whitebox"></div>
<div class="border"></div>
</div>
You can just remove the offsets like below, it will get the small box centered with the existing rules you set on everything else.
.whitebox {
...
/* top: 0; */
/* left: 0; */
}
Edit: The above works in Chrome, but doesn't seem to be working in Firefox.
In fact, I would simplify the entire code as follows. It should work everywhere where flexbox is supported.
.bluebox {
display: flex;
align-items: center;
justify-content: center;
height: 16px;
width: 16px;
background-color: #0073FF;
border-radius: 4px;
}
.whitebox {
height: 8px;
width: 8px;
background-color: white;
border-radius: 4px;
}
<div class="bluebox">
<div class="whitebox"></div>
</div>
I would rather use the usual method for centering: The container gets position: relative and defined width and height, the elements to-be-centered inside the container get this CSS:
.centered-element {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Plus z-index values for the order in which they are above each other, and possibly opacity so they all can be seen simultaneously...
So in your example, that would be
.container {
height: 16px;
width: 16px;
background-color: white;
border-radius: 4px;
position: relative;
}
.bluebox {
height: 16px;
width: 16px;
background-color: #0073FF;
border-radius: 4px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.whitebox {
height: 8px;
width: 8px;
background-color: white;
border-radius: 4px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="container">
<div class="bluebox"></div>
<div class="whitebox"></div>
</div>
The flexbox properties are superfluous when you do it this way.
Set your divs up like this:
<div class="parent">
<div class="wrapper">
<div class="whitebox"></div>
<div class="bluebox"></div>
</div>
</div>
Then apply this css:
.parent{
display: flex;
align-items: center;
justify-content: center;
}
.wrapper{
position:relative
}
.whitebox, .bluebox{
position:absolute;
top:0;
left:0;
}
You can use margin-left and margin-top because you know the height and width of your element.
Explanation:
Move your element from top 50% and from left 50%.
Move your element 4px from right and 4px from bottom.
.container {
height: 16px;
width: 16px;
background-color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
overflow: hidden;
position: relative;
}
.bluebox {
height: 16px;
width: 16px;
background-color: #0073FF;
border-radius: 4px;
position: absolute;
top: 0;
left: 0;
}
.whitebox {
height: 8px;
width: 8px;
background-color: white;
border-radius: 4px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -4px;
margin-top: -4px
}
.border {
height: 16px;
width: 16px;
border-radius: 4px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
position: absolute;
top: 0;
left: 0;
}
<div class="container">
<div class="bluebox"></div>
<div class="whitebox"></div>
<div class="border"></div>
</div>
.q-items-container .q-item-info {
float: left;
position: relative;
width: 30.3rem;
height: 40rem;
margin: 2rem;
background: #ffffff;
cursor: pointer;
/* Add shadows to create the "card" effect */
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
transition: 0.3s;
}
.q-items-container .q-item-info .q-food-img {
width: 100%;
height: 55%;
}
.q-items-container .q-item-info .q-food-info {
position: absolute;
top: 20px;
left: 20px;
z-index: 10000;
color: white;
}
.q-items-container .q-item-info .q-stars {
background-color: #2eb82e;
padding: 2px;
margin-top: 3px;
border-radius: 3px;
}
.q-items-container .q-item-info .q-separator {
width: 100%;
height: 7px;
background-color: #6c41a6;
}
.q-items-container .q-item-info .comp-container {
width: 100%;
height: 8rem;
position: absolute;
text-align: center;
top: 275px;
/* background-color:black; */
}
.q-items-container .q-item-info .comp-container .q-review {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
}
.q-items-container .q-item-info .comp-container .q-review .review {
width: 48%;
/* margin:auto; */
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.q-items-container .q-item-info .comp-container .q-review .sep {
width: 4%;
display: flex;
padding: 5px 0 5px 0;
justify-content: center;
align-items: center;
}
.q-items-container .q-item-info .comp-container .q-review .price {
width: 48%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.q-item-info .comp-container .q-company {
width: 8rem;
height: 8rem;
border: 0.8rem solid #6c41a6;
-webkit-border-radius: 2rem;
border-radius: 4rem;
margin: auto;
}
.q-items-container .q-item-info .q-order-now {
position: absolute;
bottom: 0;
width: 100%;
padding: 1rem;
margin-bottom: 0;
height: 4rem;
background: #6c41a6;
color: #fff;
font-size: 1.4rem;
text-align: center;
}
<div class="q-items-container">
<div class="q-item-info">
<div class="q-food-info">
<div>xyz</div>
<div>yzx</div>
</div>
<img style="background: linear-gradient(rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0.55)),
rgba(0,0,0,0.55);" class="q-food-img" src="https://static.pexels.com/photos/8313/food-eating-potatoes-beer-8313.jpg">
<div class="q-separator"></div>
<div class="comp-container">
<img class="q-company" src="https://n6-img-fp.akamaized.net/free-icon/telegram-logo_318-102687.jpg?size=338c&ext=jpg">
<div class="q-review">
<div class="review">
<span style="color:#4d4d49;">24</span>
<span style="color:#898989;">Reviews</span>
</div>
<div class="sep">
<div style="width:1px;height:100%;background-color:#d7d7d7;"></div>
</div>
<div class="price">
<span style="color:#4d4d49;">$4.99</span>
<span style="color:#898989;">Avg.Price</span>
</div>
<div>
</div>
</div>
</div>
<div class="q-order-now" ng-click="goToListingPage(cart)">
<div ng-show="cart.isOpen">Order Now <span>→</span></div>
<div ng-show="!cart.isOpen && !cart.isClosed">Opens at 8</div>
<div ng-show="cart.isClosed">Closed</div>
</div>
</div>
Now i want to achieve overlay effect like
I tried with linear background gradient , but it did not work out. One thing I want to mention here is, my image is dynamically set. How can I achieve that?
Try to apply the following css, then I believe you'll be able to apply it to the right element in code.
.q-items-container .q-item-info .q-food-info {
background-image: linear-gradient(0deg, rgba(0,0,0,0), rgba(0,0,0,1));
width: 100%;
}