I've got an layout which looks like this and I'm trying to zoom image-background on hover, but I can't get this effect in any way without affecting neighbour elements (on hover it expands like this) - my aim is to zoom only image and stay inside the parent div element. Is there any workaround for this in flexbox layout? This is my code:
HTML:
<body>
<div class="index-wrapper">
<nav class="index-menu">
123
</nav>
<main class="index-main">
<div class="index-square" style="background: yellow;"></div>
<div class="index-square">
<div class="index-square-inner" style="background-image: url(assets/img/is-2.jpg); background-position: center; background-size: cover;transition: all .2s ease-in-out;">
<div style="background: rgba(0, 0, 0, 0.4);">
123
</div>
</div>
</div>
<div class="index-square" style="background: pink;">123</div>
<div class="index-square" style="background: purple;">123</div>
</main>
</div>
</body>
SCSS:
.index-wrapper {
display: flex;
flex-flow: column;
height: 100vh;
.index-menu {
box-shadow: 0 0 2px 2px #d0d0d0;
z-index: 2;
background: white;
color: black;
padding: 2em;
}
.index-main {
display: flex;
background: yellow;
flex-direction: row;
flex: 1;
flex-wrap: wrap;
.index-square {
flex-basis: 50%;
display: flex;
flex-flow: column;
.index-square-inner {
flex: 1;
width: 100%;
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
&:hover {
transform: scale(1.1);
}
div {
flex: 1;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
}
You should add overflow: hidden; to the .index-square style definition;
.index-square {
flex-basis: 50%;
display: flex;
flex-flow: column;
overflow: hidden; /*Add this here*/
See this fiddle.
Related
How do I achieve an input field that: on hover, it expands on the other sibling elements (that have the same parent)?
so for example I have:
.grandparent{
display: flex;
justify-content: space-between;
width:100%;
height:5rem;
}
.other{
background-color: #7fffd477;
display: flex;
align-items: center;
justify-content: center;
width: 5rem;
}
.parent{
background-color: #fff67f;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 12px;
}
.child-1{
background-color: #ff7f7f;
display: flex;
align-items: center;
justify-content: space-between;
height: 100%;
width: 60%;
}
.child-2{
background-color: #77ab55;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 5rem;
}
.child-2:hover{
width: 100%;
transition: all 0.5s;
}
<div class="grandparent">
<div class="parent">
<div class="child-1">
<div class="sub-child-1">1.1</div>
<div class="sub-child-2">1.2</div>
</div>
<div class="child-2">
2.0
</div>
</div>
<div class="other">
other
</div>
</div>
I want the "child-2" div to expand for the whole "parent" (yellow) div and overlay other sibling elements when I hover on it.
Anyone can help me achieve this through CSS?
For the rightmost element in parent to expand over its siblings without affecting them it needs to be positioned absolute and 'anchored' at the right hand side of parent so that the width can grow towards the left.
For the simple HTML structure given in the question where there is only one sibling of the expandable element it would be possible to achieve the required layout without changing the HTML but removing the flex from parent.
However, the question mentions 'siblings' and there is therefore a requirement to layout parent with equal spacing between all its children.
This snippet allows for this by adding a div within child-2. child-2 remains with its given width and therefore takes part in the flex calculations for parent.
However, the inner div is the one which will be positioned absolute and expand to the left.
To get positioning and dimensions correct the 5rem width of child-2 and 12px padding of parent are made CSS variables and CSS calc is used. This should make it easier to change these settings if required.
To show the increased generality, this snippet has 2 siblings (each for the demo set to child-1 settings with width 30% instead of 60%).
.grandparent {
display: flex;
justify-content: space-between;
width: 100%;
height: 5rem;
}
.other {
background-color: #7fffd477;
display: flex;
align-items: center;
justify-content: center;
width: 5rem;
}
.parent {
--pad: 12px;
/* set to the width of the parent's padding */
background-color: #fff67f;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: var(--pad);
position: relative;
}
.child-1 {
background-color: #ff7f7f;
display: flex;
align-items: center;
justify-content: space-between;
height: 100%;
width: 60%;
width: 30%;
}
.child-2 {
--w: 5rem;
/* the width of the rightmost element in parent */
height: 100%;
width: var(--w);
right: 0;
}
.child-2>* {
position: absolute;
background-color: #77ab55;
display: flex;
align-items: center;
justify-content: center;
width: var(--w);
height: calc(100% - (2 * var(--pad)));
transition: all 0.5s;
right: var(--pad);
}
.child-2:hover>* {
width: calc(100% - (2 * var(--pad)));
}
<div class="grandparent">
<div class="parent">
<div class="child-1">
<div class="sub-child-1">1.1</div>
<div class="sub-child-2">1.2</div>
</div>
<div class="child-1">
<div class="sub-child-1">1.1</div>
<div class="sub-child-2">1.2</div>
</div>
<div class="child-2">
<div>
2.0
</div>
</div>
</div>
<div class="other">
other
</div>
</div>
I have adjusted the HTML structure: .child-1 is now after .child-2.
The CSS for .parent now includes flex-direction: row-reverse.
It is now possible to easily affect .child-1 via CSS (display: none).
.grandparent {
display: flex;
justify-content: space-between;
width: 100%;
height: 5rem;
}
.other {
background-color: #7fffd477;
display: flex;
align-items: center;
justify-content: center;
width: 5rem;
}
.parent {
background-color: #fff67f;
display: flex;
justify-content: space-between;
flex-direction: row-reverse; /* Added */
align-items: center;
width: 100%;
padding: 12px;
}
.child-1 {
background-color: #ff7f7f;
display: flex;
align-items: center;
justify-content: space-between;
height: 100%;
width: 60%;
}
.child-2 {
background-color: #77ab55;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 5rem;
}
.child-2:hover {
width: 100%;
transition: all 0.5s;
z-index: 10;
}
/* Added */
.child-2:hover+.child-1 {
display: none;
}
<div class="grandparent">
<div class="parent">
<div class="child-2">
2.0
</div>
<div class="child-1">
<div class="sub-child-1">1.1</div>
<div class="sub-child-2">1.2</div>
</div>
</div>
<div class="other">
other
</div>
</div>
By design flex is (initially) a single lane of content and wasn't made specifically for grids.
I currently use flex-wrap: wrap; but it's not really made for making grids -- even though it's probably the first option you try to make one.
Moreover I think it's not the only way to create grid-like layouts.
So is this the most accurate (proper) way? of creating a grid in flex?
Or are there better alternatives?
Edit (after 2 answers were posted): just to clarify, I'm not looking for display: grid; I'm asking what is the most proper/accurate way of doing it in flex. (See css flex grid)
(Of course display: grid is a proper way for making grids with CSS grid. That is not what the question is asking.)
My advise is to go with display: grid.
To get started you have to define a container element as a grid with
display: grid, set the column and row sizes with grid-template-columns
and grid-template-rows, and then place its child elements into the
grid with grid-column and grid-row.
This is an useful post about https://css-tricks.com/snippets/css/complete-guide-grid/
And this is a complete example:
The style:
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
background-color: red;
padding: 1px;
}
.grid-item {
background-color: rgba(255, 255, 255, 0.8);
border: 1px solid #000;
padding: 20px;
font-size: 30px;
text-align: center;
}
and the layout:
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
</div>
so i came up with this its not perfect but you could tweak it to make it what you want i think...https://codepen.io/colinthedev/pen/ExKwVVZ
document.getElementsByTagName("h1")[0].style.fontSize = "6vw";
body {
font-family: system-ui;
background: #f06d06;
color: white;
text-align: center;
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
}
.mainWrapper {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-items: flex-start;
}
.flexWrapOne {
display: flex;
flex-direction: row;
width: inherit;
margin: 0 .5rem 0 1rem;
justify-content: center;
align-items: center;
}
.item1 {
display: flex;
order: 1;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 15rem;
width: 20rem;
margin: .5rem;
background: #000;
}
.item2 {
display: flex;
order: 2;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 10rem;
width: 10rem;
margin: .5rem;
background: #0D89F2;
}
.item3 {
display: flex;
order: 3;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 15rem;
width: 33rem;
margin: .5rem;
background: #89F20D;
}
.flexWrapTwo {
display: flex;
flex-direction: column;
}
.item4 {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 10rem;
width: 20rem;
margin: .5rem;
background: #000;
}
.item6 {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 10rem;
width: 10rem;
margin: .5rem;
background: #0D89F2;
}
#media screen and (max-width: 1430px) {
.flexWrapTwo {
flex-direction: row;
}
.item4 {
order: 2;
}
.item6 {
order: 1;
}
}
#media screen and (max-width: 1250px) {
.mainWrapper {
display: flex;
flex-direction: column;
justify-content: center;
}
.flexWrapOne {
flex-direction: column;
width: inherit;
}
}
<h1>👋 Hello World!</h1>
<div class="flexWrapOne">
<h1 class="item1"> ITEM-1 </h1>
<h1 class="item2"> ITEM-2 </h1>
<h1 class="item3"> ITEM-3 </h1>
</div>
<div class="mainWrapper">
<div class="flexWrapOne">
<h1 class="item1"> ITEM-4 </h1>
<h1 class="item2"> ITEM-5 </h1>
<h1 class="item3"> ITEM-6 </h1>
</div>
<div class="flexWrapTwo">
<h1 class="item4"> ITEM-7 </h1>
<h1 class="item6"> ITEM-8 </h1>
</div>
</div>
<!-- Same as above just copy pasted -->
<div class="flexWrapOne">
<h1 class="item1"> ITEM-1 </h1>
<h1 class="item2"> ITEM-2 </h1>
<h1 class="item3"> ITEM-3 </h1>
</div>
<div class="mainWrapper">
<div class="flexWrapOne">
<h1 class="item1"> ITEM-4 </h1>
<h1 class="item2"> ITEM-5 </h1>
<h1 class="item3"> ITEM-6 </h1>
</div>
<div class="flexWrapTwo">
<h1 class="item4"> ITEM-7 </h1>
<h1 class="item6"> ITEM-8 </h1>
</div>
</div>
I have a flex container with 3 children, and I am wanting to ensure that the children all align at flex-start, however the final child should sit at the bottom of the container.
Is it not possible to combine align-content with align-self?
.container {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
padding: 15px 15px 50px 15px;
height: 100%;
background: red;
width: 200px;
height: 500px;
}
.item-1,
.item-2,
.item-3 { width: 100%; }
.item-3 {
align-self: flex-end;
}
<div class="container">
<div class="item-1">One</div>
<div class="item-2">Two</div>
<div class="item-3">Three</div>
</div>
Since you want 100% width of your element, you can switch to column direction then use margin to control alignment:
.container {
display: flex;
flex-direction: column;
padding: 15px 15px 50px 15px;
height: 100%;
background: red;
width: 200px;
height: 300px;
}
.item-3 {
margin-top: auto;
}
<div class="container">
<div class="item-1">One</div>
<div class="item-2">Two</div>
<div class="item-3">Three</div>
</div>
I have a flexbox parent setted with flex-direction: row.
Inside this parent, I have two children. I would like them to have the same height!
Inside this children I have dynamic content (with variable height).
The way I'm doing, if I add text on the right child, the left one will grow.
But If the left child grows, the right one stays small.
Should not they behave in the same way?
Here is a fiddle: https://jsfiddle.net/4g6uevok/8/
HTML:
<div id="main">
<div class="left">
<div class="title">MY TITLE:</div>
<div class="left-area">
<div class="left-area-row">
<div class="left-area-row-titulo">#1</div>
<div class="left-area-row-info">A</div>
</div>
<div class="left-area-row">
<div class="left-area-row-titulo">#2</div>
<div class="left-area-row-info">B</div>
</div>
<div class="left-area-row">
<div class="left-area-row-titulo">#3</div>
<div class="left-area-row-info">AC</div>
</div>
</div>
</div>
<div class="right">
<div class="title">SECOND TITLE:</div>
</div>
</div>
CSS:
#main {
width: 100%;
height:auto;
margin-top: 30px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: stretch;
background-color: red;
}
.left{
width: 400px;
display: flex;
flex-direction: column;
background:lime;
align-items: stretch;
}
.title {
width: 100%;
font-size: 1.5em;
color:#525252;
display: flex;
justify-content: center;
margin-bottom: 20px;
font-weight: bold;
font-family: "emir-bold";
}
.left-area {
width: 100%;
display: flex;
flex-direction: column;
}
.left-area-row {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.left-area-row-titulo {
width: 49.5%;
display: flex;
align-items: center;
justify-content: flex-start;
background-color: #819196;
color: white;
padding: 6px;
margin:0 2px 4px 0;
}
.left-area-row-info {
width: 49.5%;
display: flex;
align-items: center;
justify-content: center;
background: #CCCCCC;
padding: 6px;
margin:0 0 4px 2px;
}
.right {
width: calc(100% - 430px);
height: 100%;
display: flex;
flex-direction: column;
background:orange;
align-items: stretch;
}
Flex items are aligned to strech by default. Your height:100% value in .right class preventing it to take whole height so try to remove height:100% to the .right element
#main {
width: 100%;
height: auto;
margin-top: 30px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: stretch;
background-color: red;
}
.left {
width: 400px;
display: flex;
flex-direction: column;
background: lime;
align-items: stretch;
}
.title {
width: 100%;
font-size: 1.5em;
color: #525252;
display: flex;
justify-content: center;
margin-bottom: 20px;
font-weight: bold;
font-family: "emir-bold";
}
.left-area {
width: 100%;
display: flex;
flex-direction: column;
}
.left-area-row {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.left-area-row-titulo {
width: 49.5%;
display: flex;
align-items: center;
justify-content: flex-start;
background-color: #819196;
color: white;
padding: 6px;
margin: 0 2px 4px 0;
}
.left-area-row-info {
width: 49.5%;
display: flex;
align-items: center;
justify-content: center;
background: #CCCCCC;
padding: 6px;
margin: 0 0 4px 2px;
}
.right {
width: calc(100% - 430px);
display: flex;
flex-direction: column;
background: orange;
align-items: stretch;
}
<div id="main">
<div class="left">
<div class="title">MY TITLE:</div>
<div class="left-area">
<div class="left-area-row">
<div class="left-area-row-titulo">
#1
</div>
<div class="left-area-row-info">A</div>
</div>
<div class="left-area-row">
<div class="left-area-row-titulo">
#2
</div>
<div class="left-area-row-info">BA</div>
</div>
<div class="left-area-row">
<div class="left-area-row-titulo">
#3
</div>
<div class="left-area-row-info">C</div>
</div>
<div class="left-area-row">
<div class="left-area-row-titulo">
#4
</div>
<div class="left-area-row-info">D</div>
</div>
</div>
</div>
<div class="right">
<div class="title">SECOND TITLE:</div>
</div>
</div>
I have a front page layout for my portfolio that Im trying to implement some vertical text on. The right section (blue) is where my name will be written vertically. When I try to rotate the text via css transform, it screws up the layout when scrolling. So Im stumped. Youll have to increase the size to full page to view the layout correctly. Name should extend full length of the blue container.
https://codepen.io/marti2221/pen/BdrdZJ
<div class="container">
<div class="left">
<div class="svg-container">
<div class="svg-logo"></div>
</div>
<div class="question-container">
<p>WHO AM I?</p>
<p>WHAT DO I DO?</p>
</div>
</div>
<div class="middle">
<div class="top">
<nav>
<a>Link1</a>
<a>Link2</a>
<a>Link3</a>
<a>Link4</a>
</nav>
</div>
<div class="bottom">
<h1>Im an extremely</br> passionate User</br> Interface Design</br> +
Developer</h1>
</div>
</div>
<div class="right">
<h1></h1>
</div>
</div>
.container{
display: flex;
height: 100vh;
background: black;
}
.left{
display: flex;
flex: 1;
background: gray;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.svg-container{
display: flex;
flex-grow: 1;
background: yellow;
width: 100%;
justify-content: center;
}
.svg-logo{
height: 100px;
width: 200px;
background: orange;
}
.question-container{
display: flex;
flex-grow: 1;
background: green;
width: 100%;
flex-direction: column;
justify-content: flex-end;
align-items: flex-end;
}
p{
display: flex;
margin-right: 10px;
}
.middle{
display: flex;
flex: 3;
background: red;
flex-direction: column;
}
.top{
display: flex;
flex: 1;
background: aqua;
}
nav{
display: flex;
flex-direction: column;
margin: 65px 0 0 65px;
}
a:before {
content: '\2014';
position: absolute;
margin-left: -40px;
}
a{
margin: 10px 0 10px 0;
font-size: 24px;
}
.bottom{
display: inline-flex;
flex: 1;
background: brown;
align-items: flex-start;
}
h1{
margin-left: 25px;
font-size: 55px;
}
.right{
display: flex;
flex: .5;
background: blue;
}
.name{
transform: rotate(90deg);
}
sideways-lr alone (without transform) will solve it, though as of today only Firefox support it.
Use writing-mode: vertical-lr; in combination with transform: rotate and it will behave more as you expect
Updated codepen
Stack snippet
.container{
display: flex;
height: 100vh;
background: black;
}
.left{
display: flex;
flex: 1;
background: gray;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.svg-container{
display: flex;
flex-grow: 1;
background: yellow;
width: 100%;
justify-content: center;
}
.svg-logo{
height: 100px;
width: 200px;
background: orange;
}
.question-container{
display: flex;
flex-grow: 1;
background: green;
width: 100%;
flex-direction: column;
justify-content: flex-end;
align-items: flex-end;
}
p{
display: flex;
margin-right: 10px;
}
.middle{
display: flex;
flex: 3;
background: red;
flex-direction: column;
}
.top{
display: flex;
flex: 1;
background: aqua;
}
nav{
display: flex;
flex-direction: column;
margin: 65px 0 0 65px;
}
a:before {
content: '\2014';
position: absolute;
margin-left: -40px;
}
a{
margin: 10px 0 10px 0;
font-size: 24px;
}
.bottom{
display: inline-flex;
flex: 1;
background: brown;
align-items: flex-start;
}
h1{
margin-left: 25px;
font-size: 55px;
}
.right{
display: flex;
flex: .2;
background: blue;
flex-direction: column;
justify-content: center;
}
.name{
display: flex;
transform: rotate(-180deg); /* changed */
background: pink;
writing-mode: tb-lr; /* for IE */
writing-mode: vertical-lr; /* added */
}
<div class="container">
<div class="left">
<div class="svg-container">
<div class="svg-logo"></div>
</div>
<div class="question-container">
<p>WHO AM I?</p>
<p>WHAT DO I DO?</p>
</div>
</div>
<div class="middle">
<div class="top">
<nav>
<a>Link1</a>
<a>Link2</a>
<a>Link3</a>
<a>Link4</a>
</nav>
</div>
<div class="bottom">
<h1>Im an extremely</br> passionate User</br> Interface Design</br> + Developer</h1>
</div>
</div>
<div class="right">
<h2 class="name">Travis Martin</h2>
</div>
</div>