Adapting text to width of container - html

I'm trying to adapt a few a elements to the total width of the container they are in.
This is the code that I currently have: http://codepen.io/anon/pen/FsgvI
HTML
<div class="box">
<div class="title">
<div class="something">
<h3>
This is foo
>
and then bar
>
and then test
</h3>
</div>
</div>
<div class="content">
asdijfg asoidf oasidf aosidf
</div>
</div>
CSS
.box {
border: 1px solid red;
display: inline-block;
}
.content {
border: 1px solid blue;
width: 170px;
height: 100px;
}
.title {
height: 30px;
}
h3, h3 > a {
text-overflow: ellipsis;
overflow: hidden;
}
How can I make the text adapt to the width of the box container? And by "adapt" I mean keep the current font size and cut (ellipsis) the text that doesn't fit inside.
Regards
Edit:
Sorry for the missunderstanding. I can't set a width to the box class because I don't know how wide it will be. I need it to be as wide as many items (content box) as there are.

This is possible with a few changes to your CSS.
Make .title position: relative; this will make h3 position relative to it
Make h3 position: absolute; to take it out of the document flow and give it width: 100%
Add white-space: nowrap; to h3 stop the contents wrapping onto the new line
Remove width: 170px; from .content to allow it to take up as much space as it needs
.box {
border: 1px solid red;
display: inline-block;
}
.content {
border: 1px solid blue;
height: 100px;
}
.title {
position: relative;
height: 50px;
width: 100%;
}
h3 {
position: absolute;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 100%;
}
<div class="box">
<div class="title">
<div class="something">
<h3>
This is foo
>
and then bar
>
and then test
</h3>
</div>
</div>
<div class="content">
asdijfg asoidf oasidf aosidf
</div>
</div>
Codepen: http://codepen.io/anon/pen/GgkJr

I had to add a width to the containing element and add the white-space: nowrap; to the .something div.
.box {
border: 1px solid red;
display: inline-block;
width:170px;
}
.content {
border: 1px solid blue;
width: 170px;
height: 100px;
}
.title {
height: 30px;
}
.something{
white-space: nowrap;
overflow:hidden;
text-overflow: ellipsis;
}

Related

How to handle wrong width calculation when sizing text-overflow div?

I am creating a splitter-resizer in Angular to adjust the width of 2 panels. There are 2 horizontal sections and the columns widths on each side needs to be the same. However, I noticed that the width calculation is wrong at the boundary that touches the text overflow element. This causes the top and bottom panels to be off by roughly the size of a single text character.
What can I do to ensure the div width respects the ngStyle setting?
EDIT: I noticed that if I set width to undefined for the blue panel2, it seems the 2 panels size and align correctly, but I think that is not the correct way.
app.component.html
<div #container class="container">
<div class="section flex-container-row">
<div [ngStyle]="stylePanel1" class="panel1">1</div>
<div class="resizer" (click)="startdrag()" (mousedown)="startdrag($event)"></div>
<div [ngStyle]="stylePanel2" class="panel2 flex-container-row">2</div>
</div>
<div class="section flex-container-row">
<div [ngStyle]="stylePanel1" class="panel1">
<div class="longtext">this is a very long text that should be cut off when resizing.</div>
</div>
<div class="resizer" (click)="startdrag()" (mousedown)="startdrag($event)"></div>
<div [ngStyle]="stylePanel2" class="panel2">4</div>
</div>
</div>
app.component.scss
* {
box-sizing: border-box;
margin: 0; padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
.container {
width: 100%;
height: 100%;
background-color: pink;
}
.section {
width: 100%;
height: 130px;
border: 1px solid magenta;
}
.flex-container-row {
display: flex;
flex-direction: row;
}
.resizer {
flex: 0 0 5px;
background-color: #ddd;
cursor: ew-resize;
}
.panel1 {
background-color: red;
width: 100px;
}
.panel2 {
background-color: blue;
}
.longtext {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
Instead of this.refContainer.nativeElement.clientWidth.
Can you please consider refContainer.nativeElement.getBoundingClientRect()

Active tab border bottom under the div instead in the div

I have made a tab wrapper with 2 tabs. Under the tabs I have a div with content.
This is my code:
.tab-wrapper {
width: auto;
padding-left: 17px;
background-color: aqua;
white-space: nowrap;
display: table-cell;
}
.content {
background-color: aqua;
}
.role-tab {
cursor: pointer;
display: inline-block;
height: 50px;
overflow: hidden;
text-align: center;
text-overflow: ellipsis;
vertical-align: middle;
margin-right: 19px;
}
.role-tab>p {
display: table-cell;
height: 50px;
overflow: visible;
vertical-align: middle;
width: 100%;
}
.role-tab-active {
border-bottom: 3px #108DE7 solid;
font-weight: bold;
}
<div class="tab-wrapper">
<div class="role-tab role-tab-active">
<p>Role tab 1</p>
</div>
<div class="role-tab">
<p>Role tab 2</p>
</div>
</div>
<div class="content">
<p>Content</p>
</div>
The styling and everything are working good. Now I want to add some padding-top so the border-bottom will go under the div. This is a screenshot what I want:
I want that the border-bottom goes under the div instead of in the div.
I have tried margin-top, padding-top and top, but it didn't work
How can I achieve when the tab is active that the border-bottom goes under the div instead inside it?
just set the margin-bttom: -3px; for the active class and its done :
.role-tab-active {
margin-bottom:-3px;
border-bottom: 3px #108DE7 solid;
font-weight: bold;
}
see below snippet :
.tab-wrapper {
width: auto;
padding-left: 17px;
background-color: aqua;
white-space: nowrap;
display: table-cell;
}
.content{
background-color: aqua;
}
.role-tab {
cursor: pointer;
display: inline-block;
height: 50px;
overflow: hidden;
text-align: center;
text-overflow: ellipsis;
vertical-align: middle;
margin-right: 19px;
margin-bottom:-3px;
}
.role-tab > p {
display: table-cell;
height: 50px;
overflow: visible;
vertical-align: middle;
width: 100%;
}
.role-tab-active {
margin-bottom:-3px;
border-bottom: 3px #108DE7 solid;
font-weight: bold;
}
<div class="tab-wrapper">
<div class="role-tab role-tab-active">
<p>Role tab 1</p>
</div>
<div class="role-tab">
<p>Role tab 2</p>
</div>
</div>
<div class="content">
<p>Content</p>
</div>
You can't move borders via padding and margin. It's not an element but part of the element.
Give the .tab-wrapper a static height instead of default auto. Whatever the size of your border, the containing div will adjust to it instead, so we give it a static height to allow overflow. And then make it display:flex.
.tab-wrapper {
width: auto;
padding-left: 17px;
background-color: aqua;
white-space: nowrap;
display: flex;
height: 50px;
}
You can see that both the parent and tab items are of 50px height, but that's not really the case when rendered. box-sizing: content-box being the default css property, your official active role tab height is 53px, thus, overflowing the div by 3px and giving the border an "under the div" effect
Fiddle: https://jsfiddle.net/c5u3wzv2/5/

Centering truncated text with offset - CSS only

I'm trying to center a title according to the screen's center, while it's container doesn't take 100% of the screen's width.
I'm also need to text to be truncated and don't want to leave a padding on the right.
This is what I've got so far - JSFiddle. You can see that the text in the yellow div is not aligned with the text bellow. If I add a padding-right to the yellow div, upon resize, the text won't take 100% of the yellow div. Any suggestions?
HTML
<div class="cont">
<div class="left-h">
place holder
</div>
<div class="middle-h">
my very long long title goes here
</div>
</div>
<div class="real-center">
my very long long title goes here
</div>
CSS
.cont{
width: 100%;
border: 1px solid black;
display: flex;
text-align: center;
}
.left-h{
flex-basis: 150px;
background-color: #e5e5e5;
}
.middle-h{
background-color: yellow;
flex-grow: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.real-center{
width: 100%;
text-align:center;
}
I finally figured this one out, and once again a pseudo helped me achive impossible things
By adding a width and a min-width it will keep the text centered according to your requirements
.middle-h::after{
content: '';
display: inline-block;
width: calc(100% - 150px);
max-width: 148px; /* 150px - 2px border */
}
Fiddle sample
Stack snippet
.cont{
width: 100%;
border: 1px solid black;
display: flex;
text-align: center;
}
.left-h{
flex-basis: 150px; /* width/height - initial value: auto */
background-color: #e5e5e5;
}
.middle-h{
background-color: yellow;
flex: 1 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.middle-h::after{
content: '';
display: inline-block;
width: calc(100% - 150px);
max-width: 148px; /* 150px - 2px border */
}
.real-center{
width: 100%;
text-align:center;
}
<div class="cont">
<div class="left-h">
place holder
</div>
<div class="middle-h">
my very long long title goes here
</div>
</div>
<div class="real-center">
my very long long title goes here
</div>
Updated
Found yet another way when answering another question which had both a left and a right item
The upside with this is one, it doesn't need predefined width.
Fiddle sample
Stack snippet
.cont {
display: flex;
text-align: center;
border: 1px solid black;
}
.cont > * {
white-space: nowrap;
padding: 2px 4px;
background: lightgray;
}
.cont > .center {
background: yellow;
overflow: hidden;
text-overflow: ellipsis;
}
.cont .left,
.cont::after {
content: '';
flex: 1;
}
.real-center{
width: 100%;
padding: 2px 4px;
text-align:center;
}
<div class="cont">
<div class="left">
place holder
</div>
<div class="center">
my very long long title goes here
</div>
</div>
<div class="real-center">
my very long long title goes here
</div>
This is tricky because you want to center the contents of middle-h within the viewport and as explained here the best way inside a flexbox container is to use absolute position so that it centers relative to the viewport. But, it's harder to get text-overflow: ellipsis; working with an absolute position element.
This is the closest approach I have found..
<div class="cont">
<div class="left-h">
place holder
</div>
<div class="middle-h">
<span class="abs-center">my very long long title goes here</span>
</div>
</div>
<div class="real-center">
my very long long title goes here
</div>
.abs-center {
position: absolute;
left: 150px;
right: 150px;
z-index: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
margin-left: 8px;
margin-right: 8px;
}
http://www.codeply.com/go/S2sw2jrn7p

CSS expand <p> to fit text inside absolutely positioned parent?

Here is a codepen with my issue http://codepen.io/anon/pen/aNWEvQ.
HTML:
<div class="dialog-wrapper">
<div class="dialog">
<p>aaaaaaaaaaaaaaaaaaaaaaaaaaaa</p>
</div>
</div>
CSS:
* {
box-sizing: border-box;
}
.dialog-wrapper {
border: 1px solid red;
position: absolute;
}
.dialog {
min-width: 50px;
max-width: 80%;
border: 1px solid green;
margin: auto;
}
p {
border: 1px solid blue;
font-size: 16px;
font-family: Arial;
}
Why does the p tag not expand to the width of the text and force .dialog and .dialog-wrapper to expand as well?
Is there CSS that can make the paragraph expand as I desire?
Since .dialog-wrapper is absolutely positioned and all left, right and width are auto, its width will be determined by the shrink-to-fit algorithm. Basically, it will be the width of the text.
Then, if you use max-width: 80% on a child, that will be smaller than the width of the text. So the text will overflow, or it will break into multiple lines.
Instead, you should add some margin:
.dialog {
margin: 0 10%;
}
* {
box-sizing: border-box;
}
.dialog-wrapper {
border: 1px solid red;
position: absolute;
}
.dialog {
min-width: 50px;
border: 1px solid green;
margin: 0 10%;
}
p {
border: 1px solid blue;
font-size: 16px;
font-family: Arial;
}
.wrapper2 {
top: 100px;
}
.wrapper2 p {
width: 253px;
}
.wrapper3 {
top: 200px;
}
.wrapper3 p {
width: 315px;
}
<div class="dialog-wrapper">
<div class="dialog">
<p>aaaaaaaaaaaaaaaaaaaaaaaaaaaa</p>
</div>
</div>
<div class="dialog-wrapper wrapper2">
<div class="dialog">
<p>aaaaaaaaaaaaaaaaaaaaaaaaaaaa</p>
</div>
</div>
<div class="dialog-wrapper wrapper3">
<div class="dialog">
<p>aaaaaaaaaaaaaaaaaaaaaaaaaaaa</p>
</div>
</div>
Change the .dialog { max-width: 100%; }
and both they will expand.
Try this :
.dialog-wrapper {
display: table;
// add other properties
}
.dialog {
display: table-cell;
// add other properties
}
p {
display: table-cell;
// add other properties
}
Now the parent container dialog-wrapper will now adjust to the width of the child elements, i.e. dialog and p.
Use word-wrap:break-word on the style for p.
Remove fixed widths of p. You may also want to give your
.dialog-wrapper a fixed width.
codepen: http://codepen.io/anon/pen/WwjddX

How to display a horizontally scrolling list next to a fixed item?

I am trying to display a list of images (equal height) in a horizontally scrolling div. This much works, but when I want to have a fixed image - a "cover" image present leftmost inside container the layout gets screwed up.
Below is the CSS and HTML of my work. If you run the snippet you can see that the list jumps to next line, instead of staying adjacent to "cover" image and scrolling horizantally. Here is the jsfiddle - http://jsfiddle.net/6x66dLdy/
I can solve it using javascript by setting width of #list programmatically, but I want to do it with CSS alone if possible.
#container {
height: 120px;
background: #ccccff;
}
#cover {
height: 100px;
margin: 10px;
display: inline-block;
vertical-align: top;
position: relative;
}
#cover img {
border: 2px solid #cc0000;
}
#list {
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
height: 100px;
margin: 10px 0;
display: inline-block;
}
.item {
height: 80px;
margin: 10px 5px;
display: inline-block;
}
<div id="container">
<div id="cover">
<img src="http://placehold.it/160x100"/>
</div>
<div id="list">
<div class="item">
<img src="http://placehold.it/120x80"/>
</div>
<div class="item">
<img src="http://placehold.it/60x80"/>
</div>
<div class="item">
<img src="http://placehold.it/120x80"/>
</div>
<div class="item">
<img src="http://placehold.it/120x80"/>
</div>
<div class="item">
<img src="http://placehold.it/120x80"/>
</div>
</div>
</div>
This happening because you don't have widths specified. You have to provide widths for both of your inner divs and also to the container. Giving explicit width to container is advisable because you can then safely assign percent widths to children.
In you use-case, you have to calculate how much width is safer for your div#cover and then use the CSS calc to calculate the remainder of the width to assign to the list. Also, remember to account for the margins you have.
Relevant CSS:
width: calc(100% - 240px);
Your fiddle: http://jsfiddle.net/abhitalks/6x66dLdy/1
It is always better to specify a proper box-sizing. So include this at the top of your CSS:
* { box-sizing: border-box; }
.
Float the #cover left and remove the display: inline-block from #list.
This will allow the cover image and images in the list be any unknown width. Setting a fixed width on the containers like the other answers would not allow this.
Fiddle: http://jsfiddle.net/6x66dLdy/4/
#container {
height: 120px;
background: #ccccff;
}
#cover {
height: 100px;
margin: 10px;
float: left;
vertical-align: top;
position: relative;
}
#cover img {
border: 2px solid #cc0000;
}
#list {
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
height: 100px;
margin: 10px 0;
}
.item {
height: 80px;
margin: 10px 5px;
display: inline-block;
}
test this
http://jsfiddle.net/6x66dLdy/3/
#container {
height: 120px;
background: #ccccff;
width:1000px;
}
#cover {
height: 100px;
margin: 10px;
display: inline-block;
vertical-align: top;
position: relative;
width:200px;
float:left;
}
#cover img {
border: 2px solid #cc0000;
}
#list {
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
height: 100px;
margin: 10px 0;
width:600px;
float:left
}
.item {
height: 80px;
margin: 10px 5px;
display: inline-block;
}
To answer your question you can specify min-width:800px; for the id #container
so it does not jump down and stay beside the main picture
here is an example http://jsfiddle.net/6x66dLdy/5/