How do I make an inline element take up space when empty? - javascript

I have an h1 and h3 tag that will erase itself and type, using theater.js. The problem is that when it erases itself to empty, the height of the div it's in get smaller, then snaps bigger when it has content again.
I want to make the h1 and h3 tag (or change the tag completely) keep its height even while empty.
Any idea?

Just wrap your h2/h3 tag in a div with display: inline-block; like this:
<div class="header2"><h2>ABCD</h2></div>
and then add this to your css:
.header2 {
min-width: 100px;
width: auto;
min-height:45px;
background-color:#333;
color:#FFF;
display:inline-block;
padding:10px;
}
Here's a jsfiddle of two h2 tags with the above properties: https://jsfiddle.net/AndrewL32/e0d8my79/21/

two possible solutions:
1) you can set min-height to the div
For example:
div{min-height:50px;}
2) or to set min-height of h2 and p1 tags
h1,p1 {
min-height:5px;
}
Demo for 2nd approach :
h1{
background:yellow;
min-height:5px;
}
<h1></h1>
Note: as paulie_D mentioned, h1 ,p and div are block level elements by default

You may use a pseudo element to force an empty space within the element and swip it away with text-indent
h1.fixed:before {
content:' ';
display:inline-block;
width:1em;
}
h1 {
background:lightgray;
box-shadow:inset 0 0 0 1px;
}
h1.fixed {
text-indent:-0.8em; /* swip off the pseudo element */
}
<h1 contenteditable="true"></h1>
<h1 class="fixed" contenteditable="true"></h1>
else, use the :empty pseudo-class
h1:empty:before {
content:'|';
}
<h1 contenteditable="true"></h1>

Related

Margin issue with jquery load()

I am loading html page inside a div with jquery. It does work fine.
var loginBtn = $("#loginBtn");
var loginPage = $("#login");
var submitBtn = $("#submitBtn");
var submitPage = $("#submit");
var checkBtn = $("#checkBtn");
var checkPage = $("#check");
loginPage.load( "login.html" );
submitPage.load( "submitPoints.html" );
checkPage.load( "checkPoints.html" );
body {
margin: 0 !important;
padding: 0 !important;
background-color: white;
}
#mainFrame {
width: 100%;
height: 300px;
background-color:cadetblue;
padding-top: 0;
margin-top: 0px;
position: relative;
}
<div id="mainFrame">
<div id="login"></div>
<div id="check"></div>
<div id="submit"></div>
</div>
My issue is that if the loaded html has no content, the margin between the parent document body (white) and the top of the loaded html (green) is none (that's what I want, it's ok).
However as soon as I add content to the loaded html, a gap is generated at the top of the page :\
I thought it was all about setting some line-height prop in the css but it seems helpless.
Any ideas what I am doing wrong ?
What you are seeing is the top margin of the first piece of content overflowing its container (also known more commonly as margin collapsing):
body {
background:yellow;
}
#container {
background:green;
height:300px;
}
<div id="container">
<h1>I have a top margin of 1em by default that is overflowing into the body.</h1>
</div>
If you give your container element a padding of that same amount, the margin space of the body won't be used and the element will be pushed down in the green area.
body {
background:yellow;
}
#container {
background:green;
height:300px;
padding:1em;
}
<div id="container">
<h1>I have a top margin of 1em by default that is now contained within my parent.</h1>
</div>
Or, you could set the top margin of the first piece of content to zero:
body {
background:yellow;
}
#container {
background:green;
height:300px;
}
#container > h1:first-child { margin-top:0; }
<div id="container">
<h1>My top margin has been set to zero.</h1>
</div>
Finally, you could set the overflow of the content area to auto but (although this seems to be the popular answer), I don't prefer this approach as you run the risk of unintended fitting of the content as the content changes and/or the container size changes. You give up a bit of sizing control:
body {
background:yellow;
}
#container {
background:green;
height:300px;
overflow:auto;
}
<div id="container">
<h1>The content area has had its overflow set to auto.</h1>
</div>
When you load new content it gets rendered in the document and those new elements might have properties. In this case, most probably the Login has a margin value. Another option is that it has a class or some selector that is being picked up by a CSS file which appends the margin to it.
Easiet way would be to right-click on the Login element, choose inspect, and analyze the style of the element with web-dev / style.
If you want to keep the margin on the inner content, you should set an overflow. Look what happens when we remove the overflow: auto line from .content > div (try clicking the box after running the code sample below).
This is because of margin collapsing. The margin on the inner content is combined with the margin on the outer element and applied on the outer element, i.e. two margins of the two elements are collapsed into a single margin.
document.querySelector('.content').addEventListener('click', (e) => {
e.target.classList.toggle('overflow');
});
html,
body {
margin: 0;
padding: 0;
}
.outer {
width: 200px;
background: red;
}
.content > div {
width: 100%;
height: 300px;
background: cadetblue;
cursor: pointer;
}
.content > div.overflow {
overflow: auto;
}
.test {
margin: 10px;
display: block;
}
<div class="outer">
<div class="content">
<div><span class="test">Test</span></div>
</div>
</div>

How to set a max-width only to text nodes not in a tag?

I have mixed well and bad formatted text from a legacy wordpress database. Well formated is inside p tags and bad formatted is outside. So at the end the HTML is like that:
<div>
<p>Good text</p>
<blockquote>Good text</blockquote>
Problematic text <strong>like this</strong> one.
<p>Good text</p>
</div>
The p text has a max-width set and is centered:
p {
max-width: 300px;
margin: 0 auto;
padding: 10px;
}
The blockquote element or other divs are not width-limited.
As you can see in this fiddle example, my problem is that the non-p text is left-aligned. I don't know if it's possible to center using just CSS. Using javascript my approach was to do this:
jQuery("div").contents().filter(function() { return this.nodeType === 3; }).wrap('<p>');
This is ok in general, buy when you have strong or em tags in the middle it doesn't work (example).
So, is CSS able to do this? If not, how to do in Javascript? Of course, I prefer the CSS option, but JS is a better option than reformat the whole database :)
Clarification: The objective is to limit with max-width only the p-tags and the bad-fomatted text elements (which include text and some tags like strong or em). Other elements must have 100% width, it is, not limited by the 300px max-width (i.e. blockquote must use all the available screen size).
Here's a jQuery solution that will wrap the contents that aren't already in <p> or <blockquote>.
Can be easily adapted to include other acceptable tags
var $container = $('div'),
$contents = $container.contents();
var validTags = ['P', 'BLOCKQUOTE'];
var newP = null;
$contents.each(function (i) {
if (this.nodeType === 3 || $.inArray(this.tagName, validTags) == -1) {
if (!newP) { // start creating a new <p>
newP = $('<p style="color:red">')
}
newP.append(this); // append to the new <p>
} else {
if (newP) {
$(this).before(newP); //insert new <p> if there is one
newP = null; //reset
}
}
/* in case text is after all valid tags, add to end */
if (i == $contents.length - 1 && newP) {
$container.append(newP);
}
});
Note that <div> can't be appended to <p> (invalid child) so this approach would probably need some more refinement for situations like that. It does work on sample provided however
DEMO
To center all the content inside the div:
CSS:
div {
text-align: center;
}
To center some divs (example 1st and 3rd from 4), selecting them by id:
CSS:
div#sect1, div#sect3{
text-align: center;
}
HTML:
<div id="sect1>
<!-- contents -->
</div>
<div id="sect2>
<!-- contents -->
</div>
<div id="sect3>
<!-- contents -->
</div>
<div id="sect4>
<!-- contents -->
</div>
Try adding the same styles to the body and the strong tags:
strong {
font-weight: normal; margin: 0 auto;
padding: 10px;}
body {
max-width: 300px;
margin: 0 auto;
padding: 10px;
}
Why don't you apply the max-width on the container element and remove it from other descendent elements.
div.container {
max-width: 300px;
margin: 0 auto;
}
check this fiddle.
EDIT:
you can use the negative margins if you know your main container width. e.g. use -150px margin if your content area is 300px and it's container is 600px and you want bloquote to be 600px wide.
Fiddle
<style>
body{
text-align:center;
}
div:before{
text-align:center;
max-width:300px;
margin:0 auto;
}
p{
max-width: 300px;
margin: 0 auto;
padding: 10px;
}
blockquote{
font-size: 2em;
width:100%;
margin:0 auto;
}
</style>

How to include child div into parent div automatically?

Is there any way how to add a child div into parent divs. The child div is still same (without changes) but content of parent div is variable. Parent div contains child div automatically like CSS div::before but with whole div in it not just text.
Basically for each parent automatically generate same child.
See figure
sample of parent and child divs
How can I make it via CSS ? (or JS)
CSS cannot generate content (as such) it can only style it.
If the element is not present in the HTML nothing will happen.
It is possible to add "pseudo content" with a pseudo element but the primary purpose of these pseudo-elements is enhancement not addition of "content". Also they cannot contain HTML.
It would be possible to use a pseudo element with a bg image in this instance as this is essentially styling.
JSfiddle Demo
div {
height:250px;
width:250px;
display: inline-block;
margin: 25px;
position: relative; /* required */
}
div:after {
content:"";
/* required */
position: absolute;
bottom:25px;
right:25px;
background-image: url(http://www.webdevelopersnotes.com/how-do-i/thumbs/shortcut-arrow.jpg);
height:75px;
width:75px;
background-size:cover;
}
.one {
background: red;
width:300px;
}
.two {
background: lightblue;
height:300px;
}
<div class="one"></div>
<div class="two"></div>
Not sure I understood your question so I will just give you a solution and then you comment your requirements.
You can have a div that contains another child div which is positioned inside the parent but does not change when you add more content to the parent.
Here is a fiddle:
http://jsfiddle.net/1fohx3qf/
.parent {
border:2px solid black;
padding:5px;
position:relative;
width:124px;
height:120px;
}
.child {
border:2px solid red;
padding:30px;
position:absolute;
bottom:5px;
right:10px;
}
It's not completely clear to me what the problem/issue is, but it sounds like you are looking for JS code like this:
var child = document.createElement('div');
child.innerHTML = '<p>Child!</p>';
var parent = document.createElement('div');
parent.innerHTML = '<p>Parent 1</p>';
parent.appendChild(child);

Problem setting parent div width the same as child div width

I have the following markup:
<div class="head_title">
<img src="/path/to/image.png">
<h1 id="entryTitle">
<!--Cufon Font-->
</h1>
</div>
I want the img element to stretch to the full width of the 'head_title' div. The trouble arrives when I try and set the 'head_title' div to be as wide as the 'entryTitle' child h1 tag. Here's the CSS I'm using:
.head_title {
display:block;
float:left;
position:relative;
height:40px;
}
.head_title img {
height:100%;
width:100%;
display:block;
}
.head_title h1 {
color:#fff;
position:absolute;
top:0;left:0;
z-index:1;
padding:0 0 0 5px;
}
The underlying img element contains the background for the parent div - I don't want to use the CSS background-image attribute because the parent div's width will constantly be changing and I don't want it to cut off a static background image.
I tried using JavaScript's outerWidth and jQuery's .css("width") and .width() methods but nothing seems to work.
These elements have a width of 0px, because you assigned the float:left property to div.head_title. Because of this float definition, the div doesn't stretch to the full width.
The image has a width of 100%, 100% of zero is still zero. The h1 element is positioned absolutely, so that element doesn't increase the width either.
To increase the width of div.head_title, you have to specify a width (width:!00%, for example), or remove the float property.
or you could also do this....
<div class="head_title">
<img src="/path/to/image.png">
<h1 id="entryTitle">
<!--Cufon Font-->
</h1>
</div>
.head_title{
float: left;
position:relative;height:40px;
}
.head_title img {
position:absolute;top:0;left:0;z-index:-1; width: 100%; height: 100%;
}
.head_title h1{color:#999;padding:0 0 0 5px;}
sample here

How to refresh the size of a div after adding elements to it

I have an element like this:
<div id="content" style="border: 2px solid black">
</div>
And through JQuery I add some new stuff:
$("#content").append($('<div></div>').addClass("box"));
where
.box { margin: 10px; padding: 10px; border: 1px solid black }
But the outer div does not resize when I do this, so I get an inner box that is sticking out of a solid outer box. How can I get the outer box to resize itself when I add this inner box?
Correct the selector if it's not a typo
$("#content") // id="content" (correct)
$("content") // tagName = content
And change the display of the div to inline-block
#content {
display: inline-block;
}
Then the div will not occupy the whole row.
try this:
js
$('#content').append('<div class="box"> </div>');
html
<div id="content" style="border:2px solid black;overflow:hidden;">
</div>
I hope his help!
#content is not resizing, since it's width is probably set in your CSS.
Either make it wider, or specifically size it appropriately.
Looks like #content must be over 40px wide, since the inner div has 10 margin and 10 padding, which is 20 on the left and 20 on the right.
So, something like:
$("#content").css("width","100%").append($('<div></div>').addClass("box"));
Or better yet, set up your CSS at the right width to begin with:
#content { width: ... ; }
If you are floating .box within #content then set the overflow of #content to auto(or hidden), otherwise the outer box doesn't "see" the floating inner boxes:
#content { overflow: auto; }
In my case I added:
#property { overflow: auto; }
and now size of elements is being recalculated when I show or hide elements.

Categories