I am currently using this solution for modified for my use case specifically here. When I originally saw the design I figured that I would make two divs inside one flexbox container, the div on the right would be z index'd above the one on the right. Something like...
.container {
display: flex;
width: 200px;
flex-direction: row;
}
.left-side {
flex: 4;
background-color: red;
}
.right-side {
flex: 1;
background-color: orange;
z-index: 3;
border-style: 2px solid white;
border-radius: 50%;
}
<div class="container">
<div class="left-side">
View Cart
</div>
<div class="right-side">
3
</div>
</div>
This doesn't layer my elements on top of one another at all because they are positioned next to each other. So my question is:
How can I use make a layered layout while still taking advantage of all the nice positioning flexbox allows without the position absolute / position relative solution that I'm hacking together? Or, is this position absolute / relative the correct way to solve my problem?
You can apply the red background to the container, and use transform: translateX(50%) to move the orange circle half way outside of the container to pull off that effect.
.container {
display: flex;
width: 200px;
flex-direction: row;
background: red;
position: relative;
color: white;
}
.container:before {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
content: '';
}
.container:before,
.count {
border: 2px solid white;
}
.left-side {
flex-grow: 1;
}
.center {
display: flex;
justify-content: center;
align-items: center;
}
.count {
width: 50px;
height: 50px;
background-color: orange;
border-radius: 50%;
transform: translateX(50%);
}
<div class="container">
<div class="left-side center">
View Cart
</div>
<div class="right-side">
<div class="count center">3</div>
</div>
</div>
Negative margins
You can use negative margins to solve the problem without using position absolute/relative solution.
.container {
display: flex;
width: 200px;
flex-direction: row;
}
.left-side {
flex: 4;
background-color: red;
}
.right-side {
flex: 1;
background-color: orange;
z-index: 3;
border-style: 2px solid white;
border-radius: 50%;
margin-left: -60px;
text-align: center;
}
<div class="container">
<div class="left-side">
View Cart
</div>
<div class="right-side">
3
</div>
</div>
Related
Let's say I have a couple elements arranged in a column (using flexbox):
And I would like to "spotlight" element #2 in green and set it aside, but let the rest of the elements remain ordered in a column:
Is there a way to do this with just CSS and retain dynamic layout?
I've thought of a workaround by duplicating the green element and wrapping all of this in another flexbox layout ([2[1234]]) so that in the column case, the first green element is hidden ([#[1234]) whereas in the wider case, the second element is hidden ([2[1#34]), but this is a bit messy in the markup - and actually causes issues when the element has some kind of state (e.g. a <video>) that is expected to be retained in both cases.
I've also thought about using position: absolute on the green element, but I couldn't get that to work nicely either: once I set position: relative on the top-level (black) container, I can position the green element where I want, but setting position: absolute on the column container (red) so that I can position in to the right means green element is now positioned relative to the column container again.
Is there a solution I'm overlooking?
Yes you can do this using just CSS. Here's the code for the answer to your question.
HTML:
<div class="gridcontainer">
<div class="display">
</div>
<div class="flexcontainer">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
</div>
</div>
CSS:
.gridcontainer{
display: grid;
background: yellow;
grid-template-columns: 1fr .5fr;
height: 20em;
}
.flexcontainer{
background: skyblue;
padding: .5em;
grid-column: 2;
display: flex;
flex-flow: column nowrap;
align-items: center;
}
.card{
background: pink;
border: .1em solid red;
width: 80%;
padding: 1em;
text-align: center;
}
.flexcontainer .card:hover{
position: absolute;
width: 45%;
height: 15em;
transform: translateX(-50vw) translateY(1vh);
}
const expand = document.querySelector('.expand');
expand.addEventListener('click', () => {
expand.parentNode.classList.toggle('active');
});
body {
margin: 0;
}
aside {
display: flex;
flex-direction: column;
gap: 1em;
flex-wrap: wrap;
width: 50vw;
height: 100vh;
background-color: rgba(0, 0, 0, .1);
padding: 1em;
box-sizing: border-box;
position: relative;
transition: .2s;
}
div {
flex: 1;
background-color: rgba(0, 0, 0, .1);
display: flex;
justify-content: center;
align-items: center;
order: unset;
}
.expand {
position: absolute;
right: 0;
top: 50%;
transform: translate(50%, -50%);
padding: 0;
display: flex;
border: none;
background-color: #ddd;
border-radius: 100%;
width: 24px;
height: 24px;
box-shadow: 0 0 0 3px white;
}
.expand svg {
margin: auto;
border-radius: 100%;
transition: .2s;
}
aside.active {
width: 90vw;
}
.active .expand svg {
transform: rotate(180deg);
}
.active .two {
flex: 100 0 100%;
order: -1;
}
<aside class="aside">
<button class="expand">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"><path d="M12 0c6.623 0 12 5.377 12 12s-5.377 12-12 12-12-5.377-12-12 5.377-12 12-12zm0 1c6.071 0 11 4.929 11 11s-4.929 11-11 11-11-4.929-11-11 4.929-11 11-11zm-3 5.753l6.44 5.247-6.44 5.263.678.737 7.322-6-7.335-6-.665.753z"/></svg>
</button>
<div class="one">1</div>
<div class="two">2</div>
<div class="thr">3</div>
<div class="for">4</div>
</aside>
if you want, i can answer this, but not using flexbox, using Grid.
I want to give an explanation based on color of each dot below.
The whole page is:
My HTML code for the spesific area:
<div class="dot-expl">
<div class ="dot dot-red">Ended</div>
<div class ="dot dot-green">Running</div>
<div class ="dot dot-yellow">Ready to start</div>
</div>
My whole CSS code:
.dot-expl{
display: flex;
align-items: center;
overflow:visible;
}
.dot {
height: 20px;
width: 20px;
border-radius: 50%;
display: inline-block;
}
.dot-red {
background-color: red;
}
.dot-green {
background-color: green;
}
.dot-yellow {
background-color: yellow;
}
But the result is:
I cannot find how to give more space between the dots as so as the text can be visible
You could do it with this approach by using the pseudo class ::before
I set a margin to each .dot on both sides (left & right) to have some space between the individual elements.
You could also give your wrapper a fixed width and use justify-content on the wrapper. But I assume this will make you run into other problems depending on the length of the text.
.dot-expl {
display: flex;
align-items: center;
overflow: visible;
}
.dot {
margin: 0 5px;
display: flex;
align-items: center;
}
.dot::before {
content: '';
height: 20px;
width: 20px;
border-radius: 50%;
display: inline-block;
margin-right: 2px;
}
.dot-red::before {
background: red;
}
.dot-green::before {
background: green;
}
.dot-yellow::before {
background: yellow;
}
<div class="dot-expl">
<div class="dot dot-red">Ended</div>
<div class="dot dot-green">Running</div>
<div class="dot dot-yellow">Ready to start</div>
</div>
[![Red: Centered on canvas: Black: Centered between center and top of canvas][1]][1]
Using flex, it is easy to position elements in the center of a div. But how can this be done relative to already centered elements, using flex?
Shown below in the code is the best I've come up so far. I am able to center the red square in the middle but cannot get the blue one above it to be vertically center-aligned between the red square and the top border.
.flex {
border-style: solid;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: white;
height: 100vh
}
.square {
height: 10px;
width: 10px;
}
#square1 {
background-color: blue;
}
#square2 {
background-color: red;
}
.flexdivider {
display: flex;
flex-direction: column
justify-content: center;
align-items: center;
flex: 1;
}
p {
color: white;
}
<body>
<div class="flex">
<div class="flexdivider">
<div class="square" id="square1"></div>
</div>
<div class="flexdivider">
<div class="square" id="square2"></div>
</div>
<div class="flexdivider">
</div>
</div>
</div>
</body>
[1]: https://i.stack.imgur.com/4lUop.png
I have created 2 separated approach.
h2{
color: #333;
}
.box,.fakebox{
width: 30px;
height: 30px;
background-color: red;
}
/* Example #1 */
.container-box-1{
background-color: #eee;
width: 300px;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: relative;
}
.fakebox{
opacity: 0;
}
.box2{
position: absolute;
top: 25%;
left: 50%;
transform: translate(-50%,-50%)
}
<h2>Example #1 (Using Display Flex and position absolute)</h2>
<div class="container-box-1">
<div class="box"></div>
<div class="box box2"></div>
</div>
I'm looking for advice on how to approach the layout as shown in this image.
I'm not sure if flex alone can handle the overlapping green dotted boxes (using a transform?) or if the blocks should be flex boxes and the green dotted overlapping boxes should just be relatively positioned divs? The mobile version is fairly straight-forward as there's no overlapping involved but I'm unsure how to 'slice' the design up so the CSS can handle both situations.
Below is an initial attempt using transform: scale.
.flex-box-row {
display: flex;
justify-content: space-between;
}
.flex-box-row-box {
border: 1px dashed red;
width: 30%;
text-align: center;
min-height: 200px;
}
.flex-box-dots {
max-height: 50px;
border: 1px dashed green;
transform: scale(1.5, 1);
}
.flex-box-dots::after {
content: "..................";
letter-spacing: 4px;
font-size: 18px;
color: black;
margin-left: 10px;
}
<div class="flex-box-row">
<div class="flex-box-row-box">
BLOCK 1
</div>
<div class="flex-box-dots"></div>
<div class="flex-box-row-box">
BLOCK 2
</div>
<div class="flex-box-dots"></div>
<div class="flex-box-row-box">
BLOCK 3
</div>
</div>
You can get the overlapping effect by using negative margin! Here's an example:
.container {
display: flex;
}
.red {
width: 100px;
height: 100px;
border: 2px dotted red;
}
.green {
width: 150px;
height: 20px;
border: 2px dotted green;
margin: 0 -30px;
background-color: white;
z-index: 1;
}
#media (max-width: 500px) {
.container {
flex-direction: column;
align-items: center;
}
.green {
width: 20px;
height: 150px;
margin: 0;
}
}
<div class="container">
<div class="red"></div>
<div class="green"></div>
<div class="red"></div>
<div class="green"></div>
<div class="red"></div>
</div>
As you can see in the snippet below, I have a .square-container which is positioned absolutely and it contains a square. I'm trying to vertically position the .square-container in the center of the parent div.
.container {
position: relative;
background-color: blue;
}
.square-container {
position: absolute;
top: 0;
right: 0;
height: 30px;
width: 30px;
}
.square {
width: 100%;
height: 100%;
background-color: red;
}
.hello {
padding: 15px;
}
<div class='container'>
<p class='hello'>Hello</p>
<div class="square-container">
<div class='square'></div>
</div>
</div>
For positioning absolute elements in the middle use top: 50%
And then use transform: translateY(-50%); and its centered
.container {
position: relative;
background-color: blue;
}
.square-container {
position: absolute;
right: 10px;
top: 50%;
height: 30px;
width: 30px;
transform: translateY(-50%);
}
.square {
width: 100%;
height: 100%;
background-color: red;
}
.hello {
padding: 15px;
}
<div class='container'>
<p class='hello'>Hello</p>
<div class="square-container">
<div class='square'></div>
</div>
</div>
.container{
display:flex;
align-items:center;
}
You wouldn't need absolute positioning here. If you set the container as a flex wrapper, you won't also need to position it relatively and can get rid of the square-container div as well that currently wraps the div.square element.
To push the square to the right, we could
A) use auto-margins inside the flex layout. So all that our div.square needs, is margin-left: auto, which tells the browser to push it as far as possible from its left siblings.
B) Use justify-content: space-between on our container. This tells the flex container to space out the elements to the sides.
The approaches differ very slightly and don't really matter in this example until we start adding more elements.
An updated example:
A
.container {
display: flex;
align-items: center;
background-color: skyblue;
padding: 15px;
}
.square {
height: 30px;
width: 30px;
margin-left: auto;
background-color: tomato;
}
<div class='container'>
<p class='hello'>Hello</p>
<div class='square'></div>
</div>
B
.container {
display: flex;
align-items: center;
justify-content: space-between;
background-color: skyblue;
padding: 15px;
}
.square {
height: 30px;
width: 30px;
background-color: tomato;
}
<div class='container'>
<p class='hello'>Hello</p>
<div class='square'></div>
</div>