Why don't inline-blocks wrap around floating elements? - css

Why don't inline-blocks wrap around floating elements when they are higher than this floating element?
div {
height: 3em;
width: 3em;
border: 1px dotted;
float: left;
}
p {
display: inline-block;
width: 90%;
}
<div></div>
<p>In metus tortor, tristique imperdiet ultrices quis, cursus in tellus. Nunc lacinia tristique purus, ut pretium justo eleifend tempor. Ut dictum ac ex ut molestie. In posuere lacus ac volutpat consectetur. Donec pharetra eu lectus a luctus. Morbi et cursus orci. Donec a scelerisque magna. Morbi a vulputate risus. Nunc volutpat est non ipsum porttitor rutrum. Aliquam eu tortor quis ligula fermentum rutrum. Aenean nibh tellus, varius sit amet posuere quis, efficitur in quam. Cras fringilla tortor sit amet nibh lacinia rhoncus. Quisque orci quam, feugiat at auctor maximus, vestibulum a velit.</p>
Blocks and inline elements behave as expected.

The spec says
The border box of a table, a block-level replaced element, or an
element in the normal flow that establishes a new block formatting
context (such as an element with 'overflow' other than 'visible') must
not overlap the margin box of any floats in the same block formatting
context as the element itself.
And a Block formatting context is defined like this
Floats, absolutely positioned elements, block containers (such as
inline-blocks, table-cells, and table-captions) that are not block
boxes, and block boxes with 'overflow' other than 'visible' (except
when that value has been propagated to the viewport) establish new
block formatting contexts for their contents.
(Emphasis mine)

They do. Your code is incorrect. Your <div> tag isn't wrapping around your <p> tag and you have an explicit height set on the <div> tag, so content will spill out.
This is better:
<div style="width: 400px; border: 1px dotted red; float: left;">
<p style="display: inline-block; width: 50%;">Lorem Ipsum...</p>
</div>

Related

CSS layout: keeping the box width the same at different zoom levels

This seems like a simple question, but I couldn't find anything here/with search engines.
Let's first define what I mean by "same": I mean that if I put a ruler (the plastic one) next to the screen, the box would always, in different zoom levels, be the same width in centimeters (whatever that would be).
Let's also say that I'm talking about desktop browsers, since I don't want to complicate things by taking mobile into account. Also the browser should be wide enough to let there be some extra space for zooming.
Here is the box:
https://jsfiddle.net/a4be6ov5/
<div></div>
div {
border: solid 1px #000;
width: 800px;
height: 200px;
margin: auto;
}
Now, if you zoom in/out, the box width will change. The browser's Developer Tools will always show that the width is 200px, because the way this zoom thing works. But what I would actually want, is that I would want it to match the initial width compared to that ruler of ours.
I can partly do that with viewport units, but I couldn't figure out to do it automatically by calculating something. I could only do it by manually defining all the steps at which to change the box width. This turns out to be cumbersome and there are too many steps to do it at. For example I could do this:
#media screen and (min-width: 1500px) {
div {
width: 53vw
}
}
... not very easy.
How to do this automatically for all the screen widths and zoom levels?
What about having a slider on your page which alters the font size of your body element (or selected elements)?
document.querySelector('input').addEventListener("input", evt => {
document.querySelector('.body').style.fontSize = evt.target.value + 'px'
})
.a, .b {
background-color: cyan;
width: 250px;
height: 250px;
padding: 1em;
overflow: auto;
display: inline-block;
box-sizing: border-box;
}
.a {
background-color: cyan;
}
.b {
background-color: lime;
}
<p>
Smaller <input type="range" min="10" max="22" value="16"> Larger
</p>
<div class="body">
<div class="a">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris vel aliquet mauris. Donec ipsum orci, ornare et tellus at, pretium aliquet nibh. Praesent quis tincidunt tortor. Integer ac varius nisi. Integer tempus varius justo. Quisque eget elementum sapien. Mauris id blandit arcu. Mauris dui erat, ultrices vitae ligula vitae, auctor cursus lacus.
</div>
<div class="b">
Cras venenatis, nunc in tempus dictum, justo augue imperdiet nisl, id rutrum eros quam sed arcu. Maecenas fringilla diam in erat venenatis, sed sagittis elit tincidunt. Vivamus vel varius ex, id scelerisque ante. Donec ultricies, urna at aliquet gravida, urna erat porta nibh, vel semper magna urna eu dolor. Nullam condimentum ex ligula, a fringilla tortor eleifend in. Vestibulum congue eget lectus vel congue. Praesent eget malesuada est. Nulla nec semper nunc. Mauris id nulla molestie, varius turpis ut, pulvinar tortor.
</div>
</div>

I need my column of text to be left-aligned *and* truncated to the left

I doubt this is possible, but wanted to ask just in case... Also, I did find this Q/A, but it's not the right solution for my situation (or I'm doing it wrong)...
I have a column of single lines of text (e.g. each div inside the column is white-space: no-wrap), and this column is 50% of the page's width... I can easily add overflow: hidden and text-decoration: ellipsis to get each line of text to truncate on the right-hand side, but I've been asked to make it truncate on the left (to cut-off the start of each line)...
The problem with solutions like using direction: rtl is that it causes all the lines that don't truncate to be right-aligned, and I need those to still be left-aligned... Is that possible?
Edit, to add example code:
{
width: 400px;
border: 1px solid grey;
}
#column>div {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div id="column">
<div>I'm a very long string of text and I should be truncted on my left-hand side (at the start) and not here at the right-hand side</div>
<div>I'm a shorter string -- I should be left aligned</div>
</div>
If you add direction: rtl to #column, the first line is correctly truncated at the start, but the second line is incorrectly right-aligned...
... while waiting for an update with your own code :
direction can be used twice with unicode-bidi. Wrap your text in an inline element and do the swap:
exemple you can inspire yourself from:
p {
white-space: nowrap;
text-overflow: ellipsis;
direction: rtl;
overflow: hidden;
text-align:left;
}
span {
direction: ltr;
padding: 0 1em;
unicode-bidi: bidi-override;/* punctuation comes back where suposed to be */
}
<p><span>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.</span></p>
<p><span>Pellentesque habitant.</span></p>
see :https://css-tricks.com/almanac/properties/u/unicode-bidi/ for more infos

shrink img to fit a div with a sidebar

I'm working on an old website for someone and can't understand something with it's css:
I have a div the contains the page (article) content, which includes of course some images. in the top of the div there's another div, with extra information about the article. this second div is floated to the left.
<div class="entry-content">
<div class="lefttable"> //floated to the left
//some information here
</div>
//content here, including images
</div>
somehow the imgs inside the content are full sized even on the top of the page, and where they supposed to be beside the lefttable div, they jump beneath it.
here a print-screen: https://snag.gy/qFChjB.jpg
and the page itself: http://www.bayadaim.org.il/95b
Thanks,
Itamar
The parent of your image has
an inline style rule of width: 970px
wp-caption and aligncenter classes which mean:
width: 650px !important from style.css:1271
display: block; from style.css:1257.
All the above rules forbid your element from displaying inline, side by side with the floating content that precedes it.
You need to give the parent element of your image a width that compensates the width of the floating content responsively (you can do that using max-width and calc, provided that the page container has position:relative, which it does) and also you need to set it's display to either inline, inline-block or inline-flex. I recommend inline-block.
That's the theory.
In practice, for your very specific case, you also need to compensate for some padding/margin of the left-floating elements. Here's the CSS:
#post-34917 #attachment_34937 {
display: inline-block;
max-width: calc(100% - 220px);
position: relative;
margin-left: -20px;
}
#content .aligncenter>img {
width: 100%;
height: auto;
}
#media (max-width: 1023px) {
#post-34917 #attachment_34937 {
max-width: calc(100% - 170px);
}
}
You can give a try to max-width and calc():
.lefttable {
width:200px;
float:left;
}
.right {
overflow:hidden: /* to deal with floats in and out */;
}
.right img {
max-width:calc(100% - 200px); /* where 200px is the room used by lefttable ( mind borders, padding and margins) */
}
<div class="entry-content">
<div class="lefttable"> <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
</div>
<div class="right">
<img src="http://dummyimage.com/1200x200" />
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
</div>
</div>
Using some jQuery I found the way. It is not responsive, but neither this theme I'm editing - so it's good enough for me. And of course anyone who wants to develop it, is very welcome to do so.
CSS Part
Set width for all the images wrapper (wp-caption) to the width of the main content div where it is narrower, next to the floating div.
#content .wp-caption {
width: 66%;
}
jQuery Part
//make all images in posts 100% width except images next to the left table
jQuery(document).ready(function(){
var h = jQuery(".lefttable").height(); //get left table height
jQuery('.entry-content .wp-caption').each(function(){ //loop through all .wp-captions in the content
jQuery(this).removeAttr('style') //remove any disturbing inline styles. optional.
var p = jQuery(this).position(); //get each .wp-caption position
var top = p.top; //top position
if(top > h){ //if .wp-caption is below .lefttable
jQuery(this).css("width", "initial") //change .wp-caption width to original (or anything you like)
}
});
});
That's it. I hope someone could benefit from that.
Itamar

CSS block elements with relative width?

Here's what I'm trying to pull off...
And the corresponding HTML:
<article>
<h3>Fading Forest</h3>
<p>Donec id elit non mi porta gravida at eget metus. Nullam quis risus eget urna mollis ornare vel eu leo. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Vestibulum id ligula porta felis euismod semper.</p>
<p class="permalink">example.com/12345</p>
</article>
So what I need to do is wrap each h3 and p in a box, but right now, since the h3 and p tags are block level elements, the corresponding blocks just extend the full width.
I want the width to adjust according to the content (and just apply max-width so they don't extend too wide).
This is what I've got so far, though it doesn't work...obviously. http://jsfiddle.net/hAtRs/
Forget the inline-block; it doesn't seem to be necessary.
Float and clear to the left:
h3, p {
float: left;
clear: left;
}
http://jsfiddle.net/hAtRs/20/
h3, p {
background:#999;
color:white;
padding:10px 10px 10px 80px;
margin-bottom:1px;
display:inline-block;
}
Then add line breaks after every element.

css - scrollable child of fixed element

I have a fixed div with 100% height, and within that, a child-div that's relatively positioned. The child-div holds text that can be changed, so it doesn't have a fixed height.
I want the child-div to scroll vertically if its content overflows out of the screen. I played around with the min and max height properties to achieve this, but it isn't an ideal solution, and doesn't always work.
EDIT: min and max height seemed to be ignored, almost. I calculated how much vertical area the textBox would take up for the minimum 'allowable' screen height, and set that as the height. Adding min and max height made no difference to this. The only problem with this solution is that the box is always around ~60%, so even when it doesn't need to scroll, it does. This works, but isn't ideal. If there's a way to get around this it would be great.
This is what I have so far:
<div class="content">
<div id="textbox"> some text
</div>
</div>
.content { position: fixed; height: 100%; top: 0px; right: 0px; }
#textBox {
position: relative;
top: 165px;
height: 61.5%;
overflow-y: auto;
}
Is there a better, more fool-proof way for doing this?
The following worked perfectly for me:
<style type="text/css">
#fixed {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: 1px solid black;
overflow: hidden;
background: white;
}
#scrolling {
overflow: auto;
max-height: 98%;
}
</style>
<div id="fixed">
<div contenteditable id="scrolling">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam
egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien
ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean
fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non
enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas
augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor,
facilisis luctus, metus</p>
</div>
</div>
The div's content is editable, so just add text until it scrolls. It would work on decent browser.
Live Example
Basically You have to set the overflow of your fixed element as you can see in this example, and there's a jsfiddle to play with the possibilities.
I have found a solution by testing and it seems to work. It requires 3 DIVs. First and uppermost div will be your fixed element. It will contain another div as its child, which will be positioned relatively. It will another div and this div will contain your content, it has to be positioned absolutely
Code: https://codepen.io/ltorvalds024/pen/GxKdeO

Resources