Need a little bit help here. Thanks :)
I am struggling with how to make the outer div wrap the inner div and expand upwards along with the inner content editable div.
The inner div should expand from bottom to top and the outer div should wrap it (green color should wrap the red) and expand along with it.
Note: press SHIFT+ENTER in the red div to make it expand upwards.
I have an example in the following codepen
<div style="background-color:green;">
Test Test
<div id="example" contenteditable style="background-color:red; position: absolute; bottom: 0px">
Test Test
</div>
</div>
You can use flexbox:
.outer {
background: green;
display: flex;
flex-direction: column;
/* Some minimal width */
min-height: 50vh;
}
.inner {
background: red;
margin-top: auto;
}
<div class="outer">
Test Test
<div id="example" class="inner" contenteditable>
Test Test
</div>
</div>
Both of them must be absolute and wrappers height must be 100%.
<div style="background-color:green; height: 100%; position: absolute;">
wrapper
<div id="example" style="border: 1px solid red; position: absolute; bottom: 0;">
inner
</div>
</div>
Related
We have two DIVs, one embedded in the other. If the outer DIV is not positioned absolute then the inner DIV, which is positioned absolute, does not obey the overflow hidden of the outer DIV.
#first {
width: 200px;
height: 200px;
background-color: green;
overflow: hidden;
}
#second {
width: 50px;
height: 50px;
background-color: red;
position: absolute;
left: 250px;
top: 250px;
}
<div id="first">
<div id="second"></div>
<div id="third"></div>
</div>
Is there any chance to make the inner DIV obey the overflow hidden of the outer DIV without setting the outer DIV to position absolute (cause that will muck up our complete layout)?
Also position relative for our inner DIV isn't an option as we need to "grow out" of a table TD.
#first {
width: 200px;
height: 200px;
background-color: green;
}
#second {
width: 50px;
height: 400px;
background-color: red;
position: relative;
left: 0px;
top: 0px;
}
<table id="first">
<tr>
<td>
<div id="second"></div>
</td>
</tr>
</table>
Are there any other options?
Make outer <div> to position: relative and inner <div> to position: absolute. It should work for you.
What about position: relative for the outer div? In the example that hides the inner one. It also won't move it in its layout since you don't specify a top or left.
An absolutely positioned element is actually positioned regarding a relative parent, or the nearest found relative parent. So the element with overflow: hidden should be between relative and absolute positioned elements:
<div class="relative-parent">
<div class="hiding-parent">
<div class="child"></div>
</div>
</div>
.relative-parent {
position:relative;
}
.hiding-parent {
overflow:hidden;
}
.child {
position:absolute;
}
Make sure.
parent position relative.
parent have manually assigned width and height(important as child element having absolute position).
child position absolute;
.outer{
position:relative;
width:200px;
height:100px;
overflow:hidden;
}
.inner{
position:absolute;
width:100px;
height:100px;
font-size:3rem;
}
<div class="outer">
<div class=inner>
Inner DIV to apply overflw hidden
</div>
</div>
}
You just make divs like this:
<div style="width:100px; height: 100px; border:1px solid; overflow:hidden; ">
<br/>
<div style="position:inherit; width: 200px; height:200px; background:yellow;">
<br/>
<div style="position:absolute; width: 500px; height:50px; background:Pink; z-index: 99;">
<br/>
</div>
</div>
</div>
I hope this code will help you :)
I have a container div in which everything is editable
<div data-editable data-name="main-content">
</div>
Which works fine as expected, but inside of that div there are multiple sections which all can be edited as well (due to the parent div having the editable tag) but I want to have a section (a p tag) that isn't editable whilst all the other content in that div is editable.
Apart from removing data-editable from the parent div and adding it to each individual p tag (to which there could be hundreds or even thousands) how do I block just one p tag from being editable?
I would think there is a tag like data-none-editable but I can't find anything in the docs unless I'm missing the obvious.
EDIT:
For clarification the library I'm using (as per the title) is ContentTools which can be found here: http://getcontenttools.com/
You can use this if you still face problem please let me know
.first{
height: 300px;
border:1px solid red;
}
.wrapper{
width: 500px;
height: 300px;
position: relative;
}
.second{
background-color: green;
width:200px;
height: 100px;
left: 0px;
right: 0px;
top: 10px;
margin-left: auto;
margin-right: auto;
position: absolute;
}
<div class="wrapper">
<div contenteditable="true" data-name="main-content" class="first">
</div>
<div contenteditable="false" class="second">
</div>
</div>
I have a bunch of divs that have a content div inside of them. In the content div are 3 elements, an h1, a p and a span, all left-aligned. What I want to happen is the following:
The content div should be vertically and horizontally centered
The content div should be exactly as wide as the text in the h1 or the text in the span (whichever is longer), if above the max-width these should wrap
The p should be 75% as wide as the content div but not have an impact on the content div's size (effectively being 75% as wide as the h1 or span, whichever is longer)
However I'm running into the following problems:
Problem 1: Having a long p element causes the content div to expand to its max-width no matter the size of the h1 or span. I've tried using absolute positioning to fix this but it disrupts the vertical centering of the div
Problem 2: Having a long h1 element leaves a gap where the word breaks over 2 lines making the content div not appear centered
See the code snippet below to clarify what I'm after and what's going wrong, the borders are just to help visualise what's happening.
Has anyone got an idea of how this is possible? I would like to stick to CSS as these need to be responsive, although if there is a simple JS/jQuery solution it would be considered.
EDIT: To clarify the visual effect I am after here's a run-down of why the examples are good or bad. I've also added the ability to remove borders to demonstrate what I mean by something being visually centred:
1) Good: Content div fits to width of h1, looks centered without the borders as equal space to left and right of h1
2) Good: Content div fits to width of span as it's longer than the h1, looks centered without the borders as equal space to left and right of span
Problem 1:
3) Bad: p is expanding the width of the content div, looks shifted to the left without borders as more space on right than left. If the p did not expand the div and stayed at 75% of the width this would not happen
4) Improvement on 3 but still bad: Potential fix found in various SO questions showing absolute positioning stops the p expanding the content div, but now that it is not part of the flow it messes up the vertical centering
Problem 2:
5) Bad: The problem here is the h1 element, because it is now longer than the max-width it splits into 2 lines. But the extra space between the end of the first line and the max-width of the div is kept so when removing borders it doesn't look centered because there is more space to the right than the left of the h1
6) Fixes 5 but not a solution: Manually breaking the line (using a <br>) achieves the look I need, because the h1 isn't expanded to the max-width so looks centered without the borders. This isn't feasible in the real application though because the divs can vary in width
Alternative JSFiddle Link
function toggleBorders() {
$('h1, p, span').toggleClass('bordered');
$('.content').toggleClass('content-bordered');
}
.box-holder {
display: flex;
flex-flow: row wrap;
}
.box {
flex: 0 0 380px;
display: flex;
align-items: center;
justify-content: center;
height: 350px;
border: 1px solid blue;
}
.content {
max-width: 80%;
position: relative;
}
.content-bordered {
border: 1px solid red;
}
.bordered {
border: 1px solid green;
}
p {
width: 75%;
}
.abs {
position: absolute;
}
button {
position: fixed;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="toggleBorders()">Toggle Borders</button>
<div class="box-holder">
<div class="box">
<div class="content">
<h1>1. Example Title</h1>
<p>Good Example</p>
<span>Example link to the article</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>2. Title</h1>
<p>Min Width Good Example</p>
<span>Example link to the article</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>3. Example Title</h1>
<p>But when the description gets too long then it expands the content div</p>
<span>Example link to the article</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>4. Example Title</h1>
<p class="abs">Setting absolute position avoids expansion but messes up the vertical layout</p>
<span class="abs">Example link to the article</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>5. Also Long Titles Leave White Space</h1>
<p>This doesn't look centered, see 6</p>
<span>Example link to the article</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>6. Also Long Titles<br>Leave White Space</h1>
<p>Manually breaking lines fixes this</p>
<span>Example link to the article</span>
</div>
</div>
</div>
So the answer to both of these questions, it seems, is that you cannot do this without javascript. The reason being that the CSS box model just does not work in this way.
In order to solve just the first problem you need to use absolute positioning like I tried but then use javascript to create a space for the element using a margin on the h1, something like this:
$(document).ready(function() {
function alignDescriptions() {
var pmargin = 10 * 2;
$('.abs').each(function() {
var pheight = $(this).height();
$(this).css('bottom', pmargin);
$(this).siblings('h1').css('margin-bottom', pheight + pmargin);
});
}
});
That solves the vertical centering issue when using absolute so problem 1 is fixed.
To solve the second problem, the following answer provides one solution: https://stackoverflow.com/a/33246364/7542390
I believe simply using this but also using the width of the span as a minimum would probably solve both problems as I would be literally forcing the width to the correct size so having a 75% width p element wouldn't be a problem.
It's a shame that this kind of functionality isn't in the CSS spec.
EDIT: As suspected, an adaption of the second option actually removes the need for absolute positioning of the p element. Here's the jQuery code that worked for my actual case:
$('h1').each(function() {
// references to elements
var hElem = $(this);
var pElem = hElem.siblings('p');
var sElem = hElem.siblings('span');
// store starting values
var sWidth = sElem.width();
var hHeight = hElem.height();
var hWidth = hElem.width();
// reduce width until less than span width
// or until height of h1 changes
for (var testWidth = hWidth - 1; testWidth > 0; testWidth--) {
if (testWidth <= sWidth) {
testWidth = sWidth - 1;
break;
}
hElem.width(testWidth);
if (hElem.height() !== hHeight) break;
}
// set h1 width
hElem.width(++testWidth);
// if h1 still overflows (long word) use that instead
if (hElem[0].scrollWidth > hElem.width()) {
testWidth = hElem[0].scrollWidth;
hElem.width(testWidth);
}
// set p element to 75% width
pElem.width(testWidth * 0.75);
});
Your question is very interesting.I have solved your div expansion of the description by setting the max-width as the same as your min-width. Then it cannot expand.
I can't figure out the problem with the white space and title. It looks centred to me.
Here is what I got:
.box-holder {
display: flex;
flex-flow: row wrap;
}
.box {
flex: 1 0 350px;
display: flex;
align-items: center;
justify-content: center;
height: 350px;
border: 1px solid blue;
}
.content {
min-width: 50%;
max-width: 50%;
border: 1px solid red;
}
h1,
p,
span {
border: 1px solid green;
}
p {
width: 75%;
}
.abs {
position: absolute;
}
<div class="box-holder">
<div class="box">
<div class="content">
<h1>1. Example Title</h1>
<p>Good Example</p>
<span>Link</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>2. Title</h1>
<p>Min Width Good Example</p>
<span>Link</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>3. Example Title</h1>
<p>When the description gets too long then it DOESN'T expand the content div</p>
<span>Link</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>4. Example Title Size</h1>
<p class="abs">Setting absolute position avoids expansion but messes up the vertical layout</p>
<span class="abs">Link</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>5. Also Long Titles Leave White Space</h1>
<p>This does look centered</p>
<span>Link</span>
</div>
</div>
</div>
I hope it helps and this is what you're looking for.
EDIT
Solving 5 with text-align: justify;
.box-holder {
display: flex;
flex-flow: row wrap;
}
.box {
flex: 1 0 350px;
display: flex;
align-items: center;
justify-content: center;
height: 350px;
border: 1px solid blue;
}
.content {
min-width: 50%;
max-width: 50%;
border: 1px solid red;
}
h1,
p,
span {
border: 1px solid green;
}
p {
width: 75%;
}
.abs {
position: absolute;
}
/*NEW CSS:*/
h1 {
text-align: justify;
}
<div class="box-holder">
<div class="box">
<div class="content">
<h1>1. Example Title</h1>
<p>Good Example</p>
<span>Link</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>2. Title</h1>
<p>Min Width Good Example</p>
<span>Link</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>3. Example Title</h1>
<p>When the description gets too long then it DOESN'T expand the content div</p>
<span>Link</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>4. Example Title Size</h1>
<p class="abs">Setting absolute position avoids expansion but messes up the vertical layout</p>
<span class="abs">Link</span>
</div>
</div>
<div class="box">
<div class="content">
<h1>5. Also Long Don't Titles Leave White Space</h1>
<p>This does look centered</p>
<span>Link</span>
</div>
</div>
</div>
<div id="container">
<div id="div1">
<div id="div2"></div>
</div>
</div>
I want div 2 to be in the center of div1 no matter what, no matther how much the div2 width changes. Atm the div2 only get centered of the containers width.
How can I do this? Is JS the last way to go?
CSS flexbox does this with the justify-content and align-items attributes.
Style a class named something like bullseye as:
.bullseye {
display: flex;
justify-content: center;
align-items: center;
}
Then add the class to your div1 element:
<div id=container>
<div id=div1 class=bullseye>
<div id=div2>
This box is centered<br>
horizontally and vertically.
</div>
</div>
</div>
Fiddle with it:
https://jsfiddle.net/1rd6tcra/
Documentation:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes
You give the outer div a width and the inner one you give margin 0 auto.
#container{
width: 100px;
}
#div1{
margin: 0 auto;
}
check this code below
<div id="container">
<div id="div1" style="width:100%;border:1px solid #F00;">
<div id="div2" style="width:60%;border:1px solid #F0F;">
here is my div2
</div>
</div>
</div>
make sure that your inner div has a certain width and it doesn't matter whatever the width of parent.
the css code is below
#div2{
margin:auto;
}
you can check this fiddle
The modern way to do this is:
#div1 {
position: relative:
}
#div2 {
position: relative;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
}
Say I have 3 div elements that all have width:50% but have undefined heights. Now say these elements all have the attribute float:left.
Due to the width:50% attribute, the three elements are now in a two column layout, the first element sits left of the second, and the third sits below both the first.
Now, if the first div is 50px tall, and the second div is 200px tall, the third div sits below the line created by the taller div, and thus a big white space of 150px is created between div 1 and div 3.
How can one prevent the white space from occurring?
PS, the divs are being generated dynamically!
Here's a jsfiddle
make the Second element float right
See that Working Fiddle
HTML:
<div class="First"></div>
<div class="Second"></div>
<div class="Third"></div>
CSS:
div
{
float: left;
width: 50%;
}
.First
{
height: 50px;
background-color: red;
}
.Second
{
height: 90px;
background-color: yellow;
float: right;
}
.Third
{
height: 50px;
background-color: green;
}
Edit: If you have an unknown number of div's,
something like this HTML (alter the sizes as you want)
<div style="height: 50px;"></div>
<div style="height: 90px;"></div>
<div style="height: 70px;"></div>
<div style="height: 50px;"></div>
<div style="height: 90px;"></div>
<div style="height: 70px;"></div>
<div style="height: 50px;"></div>
<div style="height: 90px;"></div>
<div style="height: 70px;"></div>
Just use this CSS:
div
{
width: 48%;
margin: 1%;
background-color: #09F;
}
div:nth-child(odd)
{
float: left;
}
div:nth-child(even)
{
float: right;
}
Check out this Working Fiddle