Flex item does not "float" after translated sibling - html

I have a problem with a translated flex item still occupying its original space so that the following flex item does not immediately follow. Please see JSFiddle or snippet for more details. I want the green rectangle to follow immediately after the red so that is will be visible within the border. I can unfortunately not translate the parent, it will have overflow: hidden so that only the child within the border is visible.
Here is a JSFiddle https://jsfiddle.net/3wv9d9dm/
Or a snippet:
.parent {
display: flex;
width: 100px;
margin-left: auto;
margin-right: auto;
border: 1px solid black;
}
.child {
flex: 0 0 100%;
}
<div class="parent">
<div class="child" style="background-color:red;transform:translateX(-100%);"><h1>1</h1></div>
<div class="child" style="background-color:green;"><h1>2</h1></div>
<div class="child" style="background-color:blue;"><h1>3</h1></div>
</div>

From MDN, emphasis mine:
The <transform-function> CSS data type denotes a function used to modify an element's appearance.
Transforming an element only modifies appearance, not position in the document flow. This means that even though the element appears to have moved its position in the DOM it continues to affect sibling/other elements because its physical dimensions remain in place prior to the transformation.
A way to get around this is to animate or modify properties that affect document flow such as margin.
.parent {
display: flex;
width: 100px;
margin-left: auto;
margin-right: auto;
border: 1px solid black;
}
.child {
flex: 0 0 100%;
}
<div class="parent">
<div class="child" style="background-color:red;margin-left:-100%;">
<h1>1</h1>
</div>
<div class="child" style="background-color:green;">
<h1>2</h1>
</div>
<div class="child" style="background-color:blue;">
<h1>3</h1>
</div>
</div>
An alternate way is to transform all elements together. This method is more performant (as it skips the layout and paint steps of the browser rendering pipeline). Visit this article on Rendering Performance for a detailed explanation.
One possible way of doing this:
let children = document.querySelectorAll('.child');
[].forEach.call(children, (child) => {
child.style.transform = 'translate(-100%)';
});
.parent {
display: flex;
width: 100px;
margin-left: auto;
margin-right: auto;
border: 1px solid black;
}
.child {
flex: 0 0 100%;
}
<div class="parent">
<div class="child" style="background-color:red;">
<h1>1</h1>
</div>
<div class="child" style="background-color:green;">
<h1>2</h1>
</div>
<div class="child" style="background-color:blue;">
<h1>3</h1>
</div>
</div>

Related

Children containers do not scale with their parent [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I have 5 child divs in a parent div. The parent div does not fill the whole "window"-width", but all 5 children share the same space and fill their parent properly.
<div class="parent">
<div class="child" style="background-color:red" >child 01</div>
<div class="child" style="background-color:blue">child 02</div>
<div class="child" style="background-color:yellow">child
03</div>
<div class="child" style="background-color:grey">child 04</div>
<div class="child" style="background-color:green">child05</div>
</div>
When I use width: 90vw; for the container of the parent div, the parent div scales, yet the child divs remain the same size. Shouldn't the child divs scale automatically with their parent? How do I get it to do that?
My CSS code:
#import url('https://fonts.googleapis.com/css?
family=Muli&display=swap');
* {
box-sizing: border-box;
}
body {
font-family: 'Muli', sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}
.parent {
display: flex;
width: 90vw;
}
According to your explanation, I think you need to give a value for a parent div width in Viewport Width(vw) and, you need to give the same width for their children div tags. For the demonstration purpose, I included five children div tags inside the parent tag and gave different colors to see their widths.
edit: I have done some changes to your CSS styles and I removed the import statement. I think it overrides our CSS styles.
* {
box-sizing: border-box;
}
body {
font-family: 'Muli', sans-serif;
display: flex;
height: 100vh;
overflow: hidden;
margin: 0;
}
.parent {
display:"flex";
width: 90vw;
}
.child{
width:"100%";
}
<div class="parent">
<div class="child" style="background-color:red" >child 01</div>
<div class="child" style="background-color:blue">child 02</div>
<div class="child" style="background-color:yellow">child
03</div>
<div class="child" style="background-color:grey">child 04</div>
<div class="child" style="background-color:green">child05</div>
</div>

Have flex children only use space if they need it to not scroll, but otherwise share space equally and scroll

I have two flex children that may either each be small or large, and I'm defining small as < 50% of the container's height and large as > 50% the container's height. The sum of the heights of the children may be larger than 100% of the container's height, in which case I'd want one or both to scroll.
If one child is small and the other is large, I'd like the small element to use exactly the space it needs: it should not shrink to accommodate the large element, nor grow to 50%, and it should not scroll its contents. I'd like the large element to use the rest of the space, and scroll its contents if necessary.
If both are large, I'd like them to each use 50% of the container's height and scroll their contents.
I have this Codepen started as an example to help illustrate what I'm trying to achieve, but unfortunately it currently does no amount of scrolling or resizing: https://codepen.io/joeysilva/pen/wvmPqLK. It has both a small-large and a large-large case.
.flex-container {
height: 100px;
width: 100px;
display: flex;
flex-direction: column;
display: inline-block;
overflow: hidden;
}
.child {
flex: 50%;
overflow: auto;
}
.small {
background: red;
height: 30px;
}
.large {
background: blue;
height: 110px;
}
<div class="flex-container">
<div class="child">
<div class="small">Small</div>
</div>
<div class="child">
<div class="large">Large</div>
</div>
</div>
<div class="flex-container">
<div class="child">
<div class="large">Large 1</div>
<div class="large">Large 2</div>
</div>
</div>
Note 1: Not use disply:inline-block and display:flex the same time. Simply add another wrapper to show elements inside a row or column.
Note 2: flex: 50%; is equivalent to flex: 1 1 50%; and this is the shorthand form of flex-grow: 1; flex-shrink: 1; flex-basis: 50%;. Here in your code no need to use them because you have strictly defined the height of elements and also the basis of 50% height is wrong since you'd like the small element to use exactly the space it needs; no grow & no shrink, so it should be omitted.
.wrapper {
display: flex;
flex-direction: row;
}
.flex-container {
height: 100px;
width: 100px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.child {
overflow: auto;
}
.small {
background: red;
height: 30px;
}
.large {
background: blue;
height: 110px;
}
<div class="wrapper">
<div class="flex-container">
<div class="child">
<div class="small">Small</div>
</div>
<div class="child">
<div class="large">Large</div>
</div>
</div>
<div class="flex-container">
<div class="child">
<div class="large">Large 1</div>
</div>
<div class="child">
<div class="large">Large 2</div>
</div>
</div>
</div>

How to move div element using css?

I am in the middle of assignment. I am trying to make https://joseff-regmi.github.io/Tutangle/ responsive, I am having trouble with the body part
and most of the css3 features (flex..) are not allowed. how can I stack middle box on the top and followed by left and right on mobile version
[![enter image description here][2]][2]
on mobile:
[2]: https://i.stack.imgur.com/M80Co.png
You can use flexbox and its order property :
.parent {
background-color: blue;
height: 400px;
width: 400px;
display: flex;
flex-direction: column;
}
#child1 {
background-color: grey;
height: 100px;
margin: 20px;
order: 2;
}
#child2 {
background-color: green;
height: 100px;
margin: 20px;
order: 1;
}
#child3 {
background-color: aqua;
height: 100px;
margin: 20px;
order: 3;
}
<div class="parent">
<label for="">This is parent</label>
<div class="child" id="child1">This is child1</div>
<div class="child" id="child2">This is child2</div>
<div class="child" id="child3">This is child3</div>
</div>
if you do not want to use flexbox, then this is a way to get your work done
show/hide desktop and mobile div based on needs using media query,
for example: display:block; for class desktop,
and display:none; for class mobile and vice-versa
<div class="parent desktop">
<label for="">This is parent</label>
<div class="child" id="child1">This is child1</div>
<div class="child" id="child2">This is child2</div>
<div class="child" id="child3">This is child3</div>
</div>
<div class="parent mobile">
<label for="">This is parent</label>
<div class="child" id="child2">This is child2</div>
<div class="child" id="child1">This is child1</div>
<div class="child" id="child3">This is child3</div>
</div>

CSS percentage getting the wrong value/misaligned nested div

I am having two problems with the checkboxes shown above. The styles applied on the parent and child are essentially:
.parent {
display: flex;
justify-content: center;
align-items: center;
width: 24px;
height: 24px;
outline: 1px solid black;
margin-right: 0.5em;
}
.child {
width: 80%;
height: 80%;
flex: none;
background-color: red;
}
The first problem is: when I go read the child's width via getBoundingClientRect().width, it shows me 19.1875, while it should be 24 * 80% = 19.2.
Secondly, how do I make the child square dead center? I have no idea why but they are all slightly to the left and the top. Side note: the parent and child in this case are both <div> elements.
EDIT:
const child = document.querySelector('.child')
console.log(child.getBoundingClientRect().width)
.parent-container {
display: flex;
justify-content: center;
align-items: center;
width: 500px;
height: 50px;
}
.parent {
display: flex;
justify-content: center;
align-items: center;
width: 24px;
height: 24px;
outline: 1px solid black;
margin: 1em;
font-size: 1.5em;
}
.child {
width: 80%;
height: 80%;
flex: none;
background-color: red;
}
<div class='parent-container'>
<div class='parent'>
<div class='child'>
</div>
</div>
<div class='parent'>
<div class='child'>
</div>
</div>
<div class='parent'>
<div class='child'>
</div>
</div>
<div class='parent'>
<div class='child'>
</div>
</div>
</div>
<h1> H1 ELEMENT </h1>
<div class='parent-container'>
<div class='parent'>
<div class='child'>
</div>
</div>
<div class='parent'>
<div class='child'>
</div>
</div>
<div class='parent'>
<div class='child'>
</div>
</div>
<div class='parent'>
<div class='child'>
</div>
</div>
</div>
The above snippet is my best effort at replicating the problem. Firstly, the logged value of the child div's width seems to be incorrect (19.1875 instead of 19.2), though it might not actually affect their appearance.
Secondly, as I have discovered, the child component is only misaligned when there's nearby element that affects their positions. As seen in the snippet, the child element in the row of checkboxes above the <h1> are perfectly centered. But the child div in the ones below it are slightly closer to the top than the bottom. While it might not look obvious, it becomes very apparent when they are scaled up, like the photo at the top.
This is observed in most browsers, though in Firefox this effect is actually reversed (closer to the bottom than top). Are there anything I can do to prevent this behavior?
I lack the in-depth knowledge about how different browsers handle subpixel rounding and rendering. But in this case, the margins and other properties expressed in em or % can cause elements to render at inconsistent positions (as we may be dealing with fractions of pixels, while still being limited by the actual pixels of the screen).
I am not aware of a general solution to this problem, but you could simply ensure that the difference of width and height between the parent and the child is divisible by 2. This difference can then be evenly distributed between left/right and top/bottom. In your case, you could for example try:
.child {
width: calc(100% - 4px);
height: calc(100% - 4px);
background-color: red;
}

Control width of flex items arranged vertically in a flex container

I'm trying to achieve the effect where the boxes labeled "HALF", take up only 50% of the width (aka they share the first row evenly).
The base requirement is that they remain in a single container. Is this possible to achieve using flexbox?
I've tried playing around with flex-grow, flex-shrink, and flex-basis but I'm afraid I'm not understanding how to make it work, or if it's even possible, given the single container requirement.
Consider this fiddle: http://jsfiddle.net/GyXxT/270/
div {
border: 1px solid;
}
.container {
width: 400px;
display: flex;
flex-direction: column;
}
.child {
height: 200px;
}
.child.half {
flex: 1 1 10em;
color: green;
}
.child:not(.half) {
flex-shrink: 2;
flex-basis: 50%;
color: purple;
}
<div class="container">
<div class="child half">
HALF
</div>
<div class="child half">
HALF
</div>
<div class="child">
FULL
</div>
<div class="child">
FULL
</div>
<div class="child">
FULL
</div>
<div class="child">
FULL
</div>
</div>
Instead of flex-direction: column, you can try a wrapping flexbox using flex-wrap: wrap; and you can set:
flex-basis: 50% for the half width divs
flex-basis: 100% for the full width divs
See that I have thrown in box-sizing: border-box to adjust for the widths when using flex-basis.
See demo below:
div {
border: 1px solid;
box-sizing: border-box;
}
.container {
width: 400px;
display: flex;
flex-wrap: wrap;
}
.child {
height: 200px;
}
.child.half {
flex-basis: 50%;
color: green;
}
.child:not(.half) {
flex-basis: 100%;
color: purple;
}
<div class="container">
<div class="child half">
HALF
</div>
<div class="child half">
HALF
</div>
<div class="child">
FULL
</div>
<div class="child">
FULL
</div>
<div class="child">
FULL
</div>
<div class="child">
FULL
</div>
</div>
The flex sizing properties -- flex-grow, flex-shrink, flex-basis and flex -- work only along the main axis of the flex container.
Since your container is flex-direction: column, the main axis is vertical, and these properties are controlling height, not width.
For sizing flex items horizontally in a column-direction container you'll need the width property.
(Here's a more detailed explanation: What are the differences between flex-basis and width?)
To achieve your layout with a single container, see another answer to this question.
If you want to stay in column-direction, you'll need to wrap the .half elements in their own container.
.container {
display: flex;
flex-direction: column;
width: 400px;
}
.container > div:first-child {
display: flex;
}
.child.half {
flex: 1 1 10em;
color: green;
width: 50%;
}
.child {
height: 200px;
width: 100%;
border: 1px solid;
}
* {
box-sizing: border-box;
}
<div class="container">
<div><!-- nested flex container for half elements -->
<div class="child half">HALF</div>
<div class="child half">HALF</div>
</div>
<div class="child">FULL</div>
<div class="child">FULL</div>
<div class="child">FULL</div>
<div class="child">FULL</div>
</div>
The base requirement is that they remain in a single container.
That can also be done without flexbox, by simply float the 2 half elements
div {
border: 1px solid;
box-sizing: border-box;
}
.container {
width: 400px;
}
.child {
height: 200px;
}
.child.half {
float: left;
width: 50%;
color: green;
}
.child:not(.half) {
width: 100%;
color: purple;
}
<div class="container">
<div class="child half">
HALF
</div>
<div class="child half">
HALF
</div>
<div class="child">
FULL
</div>
<div class="child">
FULL
</div>
<div class="child">
FULL
</div>
<div class="child">
FULL
</div>
</div>
If the purpose is to hardcode the size in CSS units, or in percentages (which was mentioned the question), #kukkuz's solution is good as it is.
If you want to size element widths according to their own individual contents, then align-tems: flex-start or similar could do the job. It's possible to deal with the dimension perpendicular to that of the flex layout itself. See a tester on the bottom of the doc page
(Old question, but previous answers were incomplete, some are misleading)