Uneven horizontally scrolling div with white-space: normal - html

I'm trying to make a horizontally scrolling div with various other divs inside of it.
<div class="slider">
<div class="item">
<div class="info">
<h1>Title</h1>
</div>
</div>
<div class="item">
<div class="info">
<h1>This is a really long title</h1>
</div>
</div>
<div class="item">
<div class="info">
<h1>Title</h1>
</div>
</div>
</div>
.slider {
white-space: nowrap;
overflow: auto;
}
.item {
display: inline-block;
position: relative;
width: 200px;
height: 150px;
margin: 10px;
background: grey;
}
.info {
position: relative;
height: 100%;
color: #fff;
white-space: normal;
}
The problem I have is that each div has a title, and when it has white-space: normal set and the title is multiple lines, it throws off the alignment of the other divs.
Here is an example of the problem in action: http://jsfiddle.net/ur16gj3m/
Is there a way to get around this? If I change .info to position: absolute, it works. I'd prefer to not use absolute positioning though.

The problem is caused by the default vertical-align: baseline property on inline elements. This causes the blocks to line themselves up with the baseline of the text. This is a problem when the text wraps as the baseline is pushed down.
Set vertical-align: top on .item
Working Example
.slider {
white-space: nowrap;
overflow: auto;
}
.item {
display: inline-block;
position: relative;
width: 200px;
height: 150px;
margin: 10px;
background: grey;
vertical-align: top;
}
.info {
position: relative;
height: 100%;
color: #fff;
white-space: normal;
}
<div class="slider">
<div class="item">
<div class="info">
<h1>Title</h1>
</div>
</div>
<div class="item">
<div class="info">
<h1>This is a really long title</h1>
</div>
</div>
<div class="item">
<div class="info">
<h1>Title</h1>
</div>
</div>
</div>

Related

CSS prevent DIV from wrapping when using text-overflow: ellipsis

I'm trying to fit some text and divs all into a single line (without wrapping) and using text-overflow: ellipsis. However in all my experimenting (I can't even recall all the things I've tried), the text fills up the entire line, and the divs get pushed down onto a new line.
I'd like the text to truncate so the blue boxes are on the same line as the text.
I'm able to get it to work with JS, but I want a pure CSS solution.
EDIT:
Sorry, I should have added some more details.
The text length is variable
The solution should allow for a responsive page design (I put the width: 400px to constrain the container, but in reality it's responsive, sorry I know my question was misleading.)
.page-container{
width: 400px;
background: yellow;
}
div.header {
white-space: nowrap;
display: inline;
width: 100%;
}
div.one-line-div {
font-size: larger;
white-space: nowrap;
width: 100%;
text-overflow: ellipsis;
display: inline-block;
overflow: hidden;
}
.move-divs {
display: inline-block;
float: right;
}
.div1, .div2, .div3, .div4 {
float: right;
margin-right: 12px;
cursor: pointer;
display: inline-block;
width: 30px;
height: 30px;
background: blue;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<body>
<div class="page">
<div class="page-container">
<div class="header">
<div class="one-line-div">Text text, so much text here, what do we do with all this text?.
<div class="more-divs">
<div class="div1">
</div>
<div class="div2">
</div>
<div class="div3">
</div>
<div class="div4">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
Have you tried flex-box? Based on what I've tested it should work for you. You'll need to wrap your text in another div, though. And also need to change some things from inline-block back to block, etc. Basically flex-box is the new layout engine that allows you to do some awesome stuff. Generally you shouldn't ever need float if you use flex-box. Check out this guide on flex-box from CSS-Tricks. You can do some amazing things with it. Let me know if you have any questions regarding my answer. I didn't want to go into too much specifics because that'd be a pretty big rabbit hole.
.page-container{
width: 400px;
background: yellow;
}
/*
You don't need this anymore with flex.
div.header {
white-space: nowrap;
display: inline;
width: 100%;
}*/
/* Updated to use flex box. */
div.one-line-div {
display: flex;
flex-direction: row;
font-size: larger;
}
/* define the style for our .text element */
.text {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
/* our .move-divs needs to be flex too */
.more-divs {
display: flex;
flex-direction: row;
}
/* I removed the floats and display inline, since you don't need them */
.div1, .div2, .div3, .div4 {
margin-right: 12px;
cursor: pointer;
width: 30px;
height: 30px;
background: blue;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<body>
<div class="page">
<div class="page-container">
<div class="header">
<div class="one-line-div">
<div class="text">
Text text, so much text here, what do we do with all this text?.
</div>
<div class="more-divs">
<div class="div1">
</div>
<div class="div2">
</div>
<div class="div3">
</div>
<div class="div4">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
The solution: put the text in a "span" element . then do the following styles
.page-container{
width: 400px;
background: yellow;
}
div.header {
white-space: nowrap;
display: inline;
width: 100%;
}
div.one-line-div {
font-size: larger;
white-space: nowrap;
width: 100%;
text-overflow: ellipsis;
display: inline-block;
overflow: hidden;
}
.move-divs {
display: inline-block;
float: right;
}
.div1, .div2, .div3, .div4 {
float: right;
margin-right: 12px;
cursor: pointer;
display: inline-block;
width: 30px;
height: 30px;
background: blue;
}
.myText {
max-width: 55%;
text-overflow: ellipsis;
overflow: hidden;
display: inline-block;
}
.more-divs {
display: inline-block
}
<div class="page">
<div class="page-container">
<div class="header">
<div class="one-line-div">
<span class="myText">Text text, so much text here, what do we do with all this
text?.</span>
<div class="more-divs"">
<div class="div1">
</div>
<div class="div2">
</div>
<div class="div3">
</div>
<div class="div4">
</div>
</div>
</div>
</div>
</div>
It is easy and best using flex or grid , though here using float as you said.
When using float this display:inline-block is not needed because float it self makes elements display inline
.page{
background: yellow;
}
.page-container{
width: 400px;
}
div.header {
white-space: nowrap;
width: 100%;
}
div.one-line-div {
font-size: larger;
white-space: nowrap;
width: 100%;
text-overflow: ellipsis;
overflow: hidden;
float: left;
}
.move-divs {
float: right;
}
.div1, .div2, .div3, .div4 {
margin-right: 12px;
cursor: pointer;
display: inline-block;
width: 30px;
height: 30px;
background: blue;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />
<body>
<div class="page">
<div class="page-container">
<div class="header">
<div class="one-line-div">Text text, so much text here, what do we do with all this text?.</div>
<div class="more-divs">
<div class="div1">
</div>
<div class="div2">
</div>
<div class="div3">
</div>
<div class="div4">
</div>
</div>
</div>
</div>
</div>
</div>
</body>

How to align overflowing text horizontally?

I have some text that can overflow the parent container:
body {
margin: 200px;
}
.container {
width: 100px;
height: 50px;
background-color: #bbb;
text-align: center;
}
.header {
white-space: nowrap;
}
<div class="container">
<div class="header">
Short Text
</div>
<div class="header">
Very long text that should not wrap and be center aligned
</div>
</div>
When text is short, it is center aligned, as expected.
However, when the text overflows the container, it's not center aligned anymore.
How could I align the text horizontally regardless of the length of the text?
Desired outcome:
html:
<div class="container">
<div class="header">
<div>Short Text</div>
</div>
<div class="header">
<div>Very long text that should not wrap and be center aligned</div>
</div>
</div>
</body>
</html>
css:
body {
margin: 200px;
}
.container {
width: 100px;
height: 50px;
background-color: #bbb;
display: flex;
flex-wrap: wrap;
}
.header {
white-space: nowrap;
position: relative;
left: 50%;
transform: translateX(-50%);
}
for demo here, https://jsfiddle.net/jinny/qs7wL4nv/33/
Use text-indent:
body {
margin: 200px;
}
.container {
width: 100px;
height: 50px;
background-color: #bbb;
text-align: center;
}
.header {
white-space: nowrap;
text-indent: -8em;
}
<div class="container">
<div>
Short Text
</div>
<div class="header">
Very long text that should not wrap and be center aligned
</div>
</div>
flexbox can do this easily
body {
margin:0 200px;
}
.container {
width: 100px;
height: 50px;
background-color: #bbb;
display:flex;
flex-wrap:wrap;
justify-content:center;
}
.header {
white-space: nowrap;
}
<div class="container">
<div class="header">
Short Text
</div>
<div class="header">
Very long text that should not wrap and be center aligned
</div>
</div>

how to make div of fixed height inside div

<style type="text/css">
#displayHeader {
img {
width: 100%;
max-width: 100%;
max-height: 100%;
}
.header-img-inner {
max-height:100%;
}
}
</style>
<div id="displayHeader" style="height: 83.03px;">
<div class="header-inner">
<div class="row">
<div id="headerCol0" class="col-xs-4 text-center header-img-wrapper">
<div class="header-img-inner">
<img src="test.svg">
<p>TEST</p>
</div>
</div>
<div id="headerCol1" class="col-xs-4 text-center header-img-wrapper">
<div class="header-img-inner">
<img src="test.svg">
</div>
</div>
<div id="headerCol2" class="col-xs-4 text-center header-img-wrapper">
<div class="header-img-inner">
<img src="test.svg">
<p>tt</p>
</div>
</div>
</div>
</div>
</div>
<div id="displayContent" style="height: 264.8px;">
<div class="inner">
</div>
<div>
</div>
<div>
</div>
<div>
Image and text go out of the div block, why is this happening?
No float left, right used. It's not working with position:relative for parent and position absolute for child, but still not work well.
I only set maximum height for image when I set in on the header-img-inner
Why not use position: inherit; so as to make the image and whatever you want inside the div to inherit the position. This might help, give it a try.
Do you want something like this?
.block {
text-align: center;
background: #c0c0c0;
border: #a0a0a0 solid 1px;
margin: 20px;
}
.block:before {
content: '\200B';
/* content: '';
margin-left: -0.25em; */
display: inline-block;
height: 100%;
vertical-align: middle;
}
.centered {
display:inline-block;
vertical-align: middle;
width: 300px;
padding: 10px 15px;
border: #a0a0a0 solid 1px;
background: #f5f5f5;
}
<div class="block" style="height: 300px;">
<div class="centered">
<h1>Some Text</h1>
<img src="Untitled-2.jpg" height="150px">
</div>
</div>
Please check this link:-https://css-tricks.com/centering-in-the-unknown/

How to make multiple divs to scroll horizontally?

I want my tiles to be in the same row, and the container to scroll horizontally, if the tiles go beyond the width of the container. Looking at the following demo, the tiles get added to the next row, so I have to scroll vertically to access them. How can I make horizontal scroll work, and keep all tiles in the same row?
.container {
width: 600px;
max-height: 140px;
border: 1px solid green;
overflow-x: scroll;
overflow-y: scroll;
white-space: nowrap;
}
.tile {
width: 200px;
height: 92px;
float: left;
margin: 10px 10px 50px 10px;
background: cornflowerblue;
}
<div class="container">
<div><img class="tile"></div>
<div><img class="tile"></div>
<div><img class="tile"></div>
</div>
You need to set overflow-x:scroll; and overflow-y: hidden; on parent, and white-space:nowrap; on inner div and also display: inline-block; on floatLeft
.container {
width: 480px;
height: 140px;
border: 1px solid green;
overflow-x: scroll;
overflow-y: hidden;
}
.inner {
height: 100%;
white-space:nowrap;
}
.floatLeft {
width: 200px;
height: 92px;
margin:10px 10px 50px 10px;
display: inline-block;
}
img {
height: 100%;
}
<div class="container">
<div class="inner">
<div class="floatLeft">
<img src="http://placehold.it/350x150" class="tile">
</div>
<div class="floatLeft">
<img src="http://placehold.it/350x150" class="tile">
</div>
<div class="floatLeft">
<img src="http://placehold.it/350x150" class="tile">
</div>
</div>
</div>
Add display: inline-block to your containing divs css:
.floatleft{
display: inline-block;
}
or alternatively you can add it as a style attribute on each div:
<body>
<div class="container">
<div style="display: inline-block" class="floatLeft">
<img class="tile">
</div>
<div style="display: inline-block" class="floatLeft">
<img class="tile">
</div>
<div style="display: inline-block" class="floatLeft">
<img class="tile">
</div>
</div>
</body>
Heres the working fiddle:
https://jsfiddle.net/edencorbin/rq0L7x7v/
HTML:
<div class="container" id="content">
<div >
<img src="img" height="190">
<img src="img" height="190">
</div>
CSS:
html, body {margin: 0; padding: 0;}
#content{
width: auto;
height:210px;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
}
#contentimg {
border: 0;
display: inline-block;
vertical-align: middle;
}
I want my tiles to be in the same row, and the container to scroll horizontally, if the tiles go beyond the width of the container.
Your .container class has a fixed with of 480px. If this is intentional then all you need to do is add display: inline-block to your .floatLeft class like so:
.container > .float-left {
display: inline-block;
}
Otherwise, you can make your .container class have a flexible width. If you like the suggestion, you can change the width to min-width: 480px that way your width will expand with your content.
.container {
min-width: 480px; /* changes occurred here */
max-height: 140px;
border: 1px solid green;
overflow-x: scroll;
overflow-y: scroll;
white-space: nowrap;
}
However, if your screen width is too small to hold many tiles, then they will align vertically in a new row, which is normal expected behavior. Or better yet, you could do both. The choice is yours.

How to make an item background visible on overflow?

I have a small dropdown selection inside overflow box. Problem is I cannot make links background fill full width. Just try to scroll:
.outer {
width: 100px;
height: 100px;
overflow: auto;
border: 1px solid black;
}
.inner a {
background: none #ccc;
display: inline-block;
white-space: nowrap;
}
.inner.block a {
display: block;
}
<p>inline-block:</p>
<div class="outer">
<div class="inner">Some link title in here.</div>
<div class="inner">Some much longer link title in here.</div>
</div>
<p>block:</p>
<div class="outer">
<div class="inner block">Some link title in here.</div>
<div class="inner block">Some much longer link title in here.</div>
</div>
Also on Playground.
I can modify CSS and HTML any way, the container has position: absolute. Also, the background is an image repeating, not a solid color.
How to make the background behind the text to extend to the edge?
Just wrap the links in another div. If you need background images per link, attach them to inner div. If you need the whole bar clickable, flip the <a>'s and the <div>'s. Like this:
<div class="outer">
<div class="background">
<div class="inner">Some link title in here.</div>
<div class="inner">Some much longer link title in here.</div>
</div>
</div>
.background {
display: inline-block;
white-space: nowrap;
}
.background .inner {
background: none #ccc;
}
JsFiddle
Hope that takes everything you needed into account.
In my example, links are clickabe in full width, and you can add repeateable background easly.
<div class="outer">
<div class="background">
<div class="inner">Some link title in here.</div>
<div class="inner">Some much longer link title in here.</div>
</div>
</div>
-
.outer {
width: 100px;
height: 100px;
overflow: auto;
border: 1px solid black;
}
.outer a{
display: block;
background: url(http://nonessentials.org/wp-content/uploads/2014/01/dots-small-pattern.png);
background-size:cover;
}
.background {
background: none #ccc;
display: inline-block;
white-space: nowrap;
}
JsFiddle
I hope this could be the solution:
<p>inline-block:</p>
<div class="outer">
<div class="table">
<div class="inner">Some link title in here.</div>
<div class="inner">Some much longer link title in here.</div>
</div>
</div>
.outer {
width: 100px;
height: 100px;
overflow: auto;
border: 1px solid black;
}
.table {
display:table;
}
.inner {
display:table-row;
}
.inner a {
background: none #ccc;
display: block;
white-space: nowrap;
}
.inner a:hover {
background-color:orange;
}
Demo: http://jsfiddle.net/jscohdL0/27/
So, wrapper div again, but with display:table property, and inner divs as table-rows... Clickable, hoverableā„¢...
Without using any wrapper:
.inner {
width: 300px;
}
.inner a {
background: none #ccc;
display: inline-block;
white-space: nowrap;
width:100%; /*addition*/
}
With wrapper:
.outer {
width: 100px;
height: 100px;
overflow: auto;
border: 1px solid black;
}
.cover {
background: none #ccc;
display: inline-block;
white-space: nowrap;
}
.inner a {
width: 100%;
display: inline-block;
}
.inner.block a {
display: block;
}
<p>inline-block:</p>
<div class="outer">
<div class="cover">
<div class="inner">Some link title in here.
</div>
<div class="inner">Some much longer link title in here.
</div>
</div>
</div>
<p>block:</p>
<div class="outer">
<div class="cover">
<div class="inner block">Some link title in here.
</div>
<div class="inner block">Some much longer link title in here.
</div>
</div>
</div>