On element resize, resize the sibling elements too - javascript

I'm trying to horizontaly resize one div using css property resize: horizonatal. There are other elements right to this div with a padding of 10px that need to follow resizable div whenever it is resized. I'm not sure what would be the best approach to do the resizing? I found some articles about DOM Monitoring, but was wondering if there is a "simpler" way to do this.

You can wrap your elements in a container with display: flex. If you tell your non-resizable element to take up the remaining space, they should flow with the resized elements before them automatically.
Here's a runnable example:
.container {
display: flex;
}
.non-resizable {
flex-grow: 1;
background: pink;
}
.resizable {
resize: horizontal;
overflow: auto;
border: 1px solid black;
margin-right: 12px;
}
<div class="container">
<div class="resizable">Hello</div>
<div class="non-resizable">world!</div>
</div>

Related

Expanding a `div` while taking its children `max-width` into consideration

My front-end skills are poor, so does my English expression. Sorry ahead.
I have these several divs (some colors and margins are added as some kind of visual assistance):
<html>
<header>
<style>
.outer-container {
margin: 2px;
padding: 2px;
border: 1px deeppink dashed;
}
.inner-container {
margin: 2px;
padding: 2px;
border: 1px deeppink dotted;
display: flex;
flex-direction: row;
align-items: center;
}
.content0 {
background-color: black;
color: white;
border: 1px red solid;
white-space: nowrap;
}
.content1 {
max-width: 500px;
background-color: black;
color: white;
flex-grow: 1;
border: 1px red solid;
white-space: nowrap;
}
</style>
</header>
<body>
<div class="outer-container" style="width: 100%" align="center">
<div class="inner-container">
<div class="content0">Placeholder</div>
<div class="content1">Placeholder</div>
</div>
</div>
</body>
</html>
Here are my expected behaviors:
The outer-container has some kind of "externally appointed" width (width: 100% in this example, but not limited to this circumstance).
The content0 is expected to have a minimum width for displaying its content. The content1 is expected to expand horizontally and occupy its "container"'s space, at most 500px.
The inner-container is expected to expand and occupy its "container"'s space, while considering the maximum width of its children. In this example, I expected it to expand until content1 reaches its max-width. Then, inner-container is aligned to the center of outer-container.
Fig1: when outer-container is narrow, inner-container simply fills the outer-container.
Fig2: when outer-container gets wider, inner-container expands until its children stop expanding, and then inner-container gets to the center of outer-container. This picture was made by mspaint, not really I know how to implement it with HTML/CSS.
However, I bumped into troubles when trying to implement the third item. I've tried many combinations and searched over again. But for each attemption , either inner-container is not expanded at all, or inner-container expands and eats up outer-container. Is it possible to implement this with HTML and CSS (and JavaScript if really needed)? And if so, how?
The closest I could get is https://jsfiddle.net/ne9phs5y/.
The content0 and content1 behave as expected but unfortunately inner-container fills the entire outer-container which might or might not be a problem. The most important part was setting flex-basis of content1 to 500px.

Creating a container that has 3 divs as columns which has horizontal draggable inner borders

so the problem is; I have 1 container that has 3 columns within it which start off with all even widths, but the borders on the middle column need to be able to be "dragged" / resized.
The ideal solution would be with CSS and HTML only.
The way I'm going about it currently is using resize: horizontal; & overflow-y: auto; Then set all initial widths.
HTML (simplified) - feel free to add more classes
<div class="container">
<div></div>
<div></div>
<div></div>
</div>
CSS
.container {
display: flex;
height: auto;
width: 100vw;
background: #fff;
> div{
overflow-y: auto;
&:first-child {
width: 500px;
resize: horizontal;
}
&:nth-child(2) {
width: 33%;
resize: horizontal;
overflow: auto;
}
&:last-child {
width: 500px;
flex: 1;
}
}
}
Ideal solution: Whole column border is draggable, but we can't use a mouse down/mouse move event handler as it's a too intensive process. Also Javascript is currently off the table - although a solution with pure JS would be a fun learning experience.
Current solution: Bottom right corner is resizable in a horizontal direction only, but you can "overdrag" and send the columns into a weird width that you have to invisibly drag back again. Just not a very smooth experience.
Is there a solution out there that does it better than what I currently have?

Keep vertical scrollbar in a fixed position independent of horizontal scroll

I currently have a grid set up that looks something like this:
<div class="grid-container">
<div class="headers"> <!-- ... --></div>
<div class="row-container">
<div class="row"> <!-- ... --></div>
<!-- ... -->
</div>
</div>
Essentially what I'd like to do is place an overflow-x on the entire grid-container (so that scrolling horizontally will scroll both the headers and the rows together), but just place an overflow-y: overlay on the row-container (so that scrolling down will only scroll through the rows and keep the grid headers in a fixed position.
I was able to do that and it looks okay, however, the vertical scrollbar on the row-container is at the far right of the row-container. I'd like it to be visible and in a fixed position (similar to how it would look if you were to place an overflow-y on the entire grid-container except without affecting the headers).
Sorry I know I probably explained this poorly, but here's a JSFiddle that should hopefully illustrate the problem I'm having: https://jsfiddle.net/4xwd5yzp/
Notice in that fiddle, you can only see the vertical scrollbar when you scroll to the end of the row-container.
Thank you in advance for any help. Ideally, I'd prefer a solution using just HTML + CSS, but I'm also open to use vanilla JS + jQuery if absolutely necessary.
EDIT: Here is an example of how it currently works (not ideal):
And here is a photo of how I want it to look:
You were very close, if you take the overflow-y style off of .row-container and add it to .grid-container and also add position: sticky; and background: white; to .headers then I believe it'll work how you want it to.
Update the width in % rather than px.
`
.grid-container {
border: 1px solid black;
height: 200px;
width: 99%x;
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
}
.row-container {
height: 150px;
width: 99%x;
overflow-y: overlay;
}
.grid-cell {
display: inline-block;
width: 250px;
}
.headers {
border-bottom: 1px solid black;
height: 50px;
width: 99%;
}
.row {
border-bottom: 1px solid lightgray;
height: 30px;
width: 99%;
}
`

How to define the width of a HTML element dynamically

I have a single container div with two child div's. The container div is 100% width. The child div's are left floated. The left div's width is not set because it's contents must decide it's width. The right div's width must be 100% minus the width of the left div.
HTML:
<div class="container">
<div class="message-name"><p>User :</p></div>
<div class="message-msg"><p>Some message</p></div>
</div>
<div class="container">
<div class="message-name"><p>User : </p></div>
<div class="message-msg"><p>Some really long message that breaks to new line because it is too long to stay on this line. mmmm mmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmmm mmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmm</p></div>
</div>
CSS:
*{margin:0;pading:0;}
.container{
width:100%;
min-height: 20px;
overflow: auto;
}
.message-name{
height: 20px;
text-align: left;
float: left;
border: 1px solid red;
}
.message-msg{
border: 1px solid red;
min-height: 20px;
float: left;
}
This is my attempt at using JQuery to dynamically set the width of the right div when it is added to the page dynamically:
$(document).ready( function(){
var nameWidth = $(".message-name").last().width();
alert(nameWidth);
$(".message-msg").last().css("width","100%").width($(".message-msg").last() - nameWidth);
});
But it doesn't change anything.
How can I get the width of the left div and then subtract that from the width of the right div to ensure the right div does not break to a new line?
Here is a JSFiddle of my attempt.
Use flexbox, it's support is wide enough for most reasonable purposes.
No scripting required, much more FLEXible!
* {
margin:0;
padding:0;
}
.container {
width:100%;
min-height: 20px;
overflow: auto;
display: flex;
flex-direction: row;
}
.message-name {
height: 20px;
text-align: left;
border: 1px solid red;
flex-shrink: 0;
}
.message-msg {
border: 1px solid red;
min-height: 20px;
flex-grow: 1;
flex-shrink: 1;
}
<div class="container">
<div class="message-name"><p>User :</p></div>
<div class="message-msg"><p>Some message</p></div>
</div>
<div class="container">
<div class="message-name"><p>User : </p></div>
<div class="message-msg"><p>Some really long message that breaks to new line because it is too long to stay on this line. mmmm mmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmmm mmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmm</p></div>
</div>
Also on JSFiddle
A more efficient way to use flexbox is to just declare the .message-msg block to be flex: https://jsfiddle.net/84vocLbk/. It'll be situated horizontally next to the .message-name and stretch the available width.
CSS:
.message-msg {
border: 1px solid red;
min-height: 20px;
display: flex;
}
Please try this
$(".message-msg").last().width($(".message-msg").last().width() - nameWidth);
Border 2px for each div is present. If you want to place it to the left then try this
$(".message-msg").last().width($(".message-msg").last().width()-2 - nameWidth-2);
DEMO without removing border
DEMO after removing the border
Add this
$(".message-msg").last().css("width","100%").width($(".message-msg").last().width() - nameWidth);
In thaat line you're setting the width to 100% then changing that width to 100% minus the variable nameWidth You have to get width of last div to do calculations
You can achieve this with CSS.
fiddle: https://jsfiddle.net/zof15z6c/7/
This works by setting the overflow of the second div to hidden or auto. if your content is just a text I suggest setting it to hidden since the text would just wrap around.
Changes to the css
.message-msg{
border: 1px solid red;
min-height: 20px;
overflow:hidden;
}
Advantages:
Works on most browsers (tested in IE7)
The browser takes care of window resizes
Cleaner code
Disadvantages
Overflow should either be hidden or auto. This will not be an issue for you since you just have text.

Vertically aligning my div within the body

Is there a CSS way to vertically align my div within the body element?
The thing is my div will have a different height each time, so its not constant.
These are the things I've tried but they dont work:
body { vertical-align: middle; }
#mainContent {
vertical-align: middle;
}
// Also this
body { margin-top: 20%; margin-bottom: 20%; }
I did it without table: (demo on dabblet.com)
The main trick in this demo is that in the normal flow of elements going from top to bottom, so the margin-top: auto is set to zero. However, for an absolutely positioned element acts the same distribution of free space, and similarly can be centered vertically at the specified top and bottom (does not work in IE7).
This trick will work with any sizes of div.
HTML:
<div></div>
CSS:
div {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
A common problem indeed. I have seen many people offering straight css solutions for this but they all require knowing the height of the element needing to be centered, so no help there.
I usually do it this way using jquery:
$(document).ready(function(){
site.resize();
$(window).resize(function(){
site.resize();
});
});
var site = {
resize: function(){
var new_margin = Math.ceil(($(window).height() - $('#mainContent').height()) / 2);
$('#mainContent').css('margin-top', new_margin + 'px');
}
};
Surprisingly (or not), the vertical-align tool actually works best for this job. Best of all, no Javascript is required.
In the following example, I am positioning the outer class in the middle of the body, and the inner class in the middle of the outer class.
Preview: http://jsfiddle.net/tLkSV/513/
HTML:
<div id="container">
<span></span><div class="outer">
<span></span><div class="inner">
</div>
</div>
</div>
CSS:
html, body {
height: 100%;
margin: 0;
padding: 0; }
#container {
text-align: center;
height: 100%; }
span {
height: 100%;
vertical-align: middle;
display: inline-block; }
.outer {
width: 100px;
height: 200px;
padding: 0;
border: 1px solid #000;
vertical-align: middle;
display: inline-block; }
.inner {
background: red;
width: 30px;
height: 20px;
vertical-align: middle;
display: inline-block; }
Vertical align works by aligning the centers of elements that are next to each other. Applying vertical-align to a single element does absolutely nothing. If you add a second element that has no width but is the height of the container, your single element will move to vertically center with this no-width element, thus vertically centering it. The only requirements are that you set both elements to inline (or inline-block), and set their vertical-align attribute to vertical-align: middle.
Note: You may notice in my code below that my <span> tag and <div> tag are touching. Because they are both inline elements, a space will actually add a space between the no-width element and your div, so be sure to leave it out.
You can do it without using tables, and without adding extra elements:
<ul>
<li>One short item</li>
<li>Any real long text...</li>
<li>Another short item</li>
</ul>
And then the CSS:
ul {
list-style-type: none;
display: table-row;
}
li {
display: table-cell;
vertical-align: middle;
}
You can see it here
It would work with any other kind of hierarchy, including div, p, etc.
Honestly, my opinion is often that if you're doing vertical alignment you should still be using a table. I know it's often frowned upon, but it is still the simplest and cleanest way to vertically center something.
HTML
<table>
<tbody>
<tr>
<td>
<div>Your DIV here.</div>
</td>
</tr>
</tbody>
</table>
CSS
td {vertical-align: middle;}

Categories

Resources