What would be the best way to implement a design that want div-containers be provides with a border, if the content of the div causes vertical scroll of the div?
CSS
div {
max-height: 100px;
overflow-y: auto;
// if content exceeds 100 px show border
border: solid 1px;
}
HTML
<div>
// Text ..
</div>
Set border if overflow.
var div = document.querySelector('div');
if (div.scrollHeight > div.clientHeight) {
div.style.border = '1px solid';
}
div {
max-height: 100px;
overflow-y: auto;
}
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
I am assuming there is some kind of event that changes or determines the content of that div.
In my humble opinion, you can not achieve that using html/css alone. You would have to use JavaScript.
https://jsfiddle.net/4u2Lurt3/
Here is a simple example of how to do that. You may need to "re-wire" a bit differently to get the exact behavior you wanted
<div id="myDiv">
Hello
</div>
<button onclick="addText()">
Click to change div
</button>
And
function checkWidth() {
var div = document.getElementById('myDiv');
if(div.offsetWidth > 100) {
div.style.border = "1px solid black"
}
}
function addText() {
var div = document.getElementById('myDiv');
div.style.width="250px";
div.innerText = "AAAAAAAAAAAAA VVVVVVEERRRRY LOOOONNNNGGG TEEEEEXXXXXTT";
checkWidth();
}
Related
I know it's possible to position a div's scrollbar on the left-hand side by simply using direction:rtl, but why the same doesn't work for the whole page?
I tried putting the same rule for both html and body but no chance and the main scrollbar still on the right.
(I know there are some hacky ways like putting a fixed div with height and width = 100% and direction:rtl that scrolls instead of main page, but isn't there any way to solve the problem directly?)
Set every elements' direction from left to right (ltr) except for body (direction: rtl)
* {
direction: ltr;
}
body {
direction: rtl;
}
Example:
* {
direction: ltr;
}
div {
padding: 5rem;
}
body {
direction: rtl;
}
<body>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</body>
<pre style="overflow-x: auto; width:100%">
Will never scroll.
</pre>
<pre style="overflow-x: auto; width:500px">
Will scroll but is not of responsive design.
</pre>
I want to have a pre-element that will be more responsive in direct relation to the parent element, but the parent element has no fixed width. Using width:100vw or even something like width: calc(100vw - 300px) is not an option because the site has too many dynamic elements. I would like to accomplish this with CSS alone. Is this an issue I am only going to be able to resolve with JavaScript?
Update:
It appears that overflow-x: auto does not work unless you use a static width. In my case everything (including parent elements) is responsive, nothing is set to a static width. I solved the problem by just using overflow-x: scroll
The question in incorrect in stating that width: 100% will result in never scrolling, as can be seen in the following examples. All of the pre tags have width: 100%.
You may have had an issue with width: 100vw because 100vw is not the same as 100%. 100vw is equal to the width of the viewport, but 100% width is the width of the nearest parent element. In the bottom two examples, 100% width is the width of their respective divs, and will be responsive.
pre {
overflow-x: auto;
width: 100%;
}
#medium-container {
padding: 10px;
width: 500px;
border: 1px dotted red;
}
#small-container {
padding: 10px;
width: 250px;
border: 1px dotted blue;
}
<pre>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</pre>
<div id="medium-container">
<pre>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</pre>
</div>
<div id="small-container">
<pre>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</pre>
</div>
I would like to expand a component's height until the bottom of the page is reached. Eventually, a scrollbar should appear inside it, depending on the content, but the page doesn't have to scroll, only the component itself should be scrollable.
The solution I found so far is the following:
<div style="height: 83vh; overflow-y: auto;">
<div class="container-fluid pt-3">
<div class="card-columns">
<div class="card" style="max-width:250px;" *ngFor="let myImg of imgList">
<img class="card-img-top" style="width:100%;" [src]="myImg">
</div>
</div>
</div>
</div>
Which is not the perfect solution, because that height: 83vh; may depend by the browser and work well only in my case. I then tried doing the following:
<div style="height: 100%; overflow-y: auto;">
but the div would overflow the web page, activating the page scroll and not the component scroll.
Any suggestion to achieve the behavior I want?
Maybe you can play around with the calc() function in CSS; you can take into account the full viewport height and substract the amount in px equal to other components in the screen, so that the component you want to fill the screen with only uses that remaining space.
If you test the snippet; the component uses enough space depending on the content inside, but if the content grows large enough to push the component to the bottom, instead of causing the whole page to scroll, it stays in place and only scrolls the content inside.
/* These styles are just for consistency */
body {
margin: 0;
}
body * {
box-sizing: border-box;
}
/*****************************************/
.top-bar {
height: 60px;
background-color: black;
}
section .component {
max-height: calc(100vh - 60px);
max-width: 900px;
margin: 0 auto;
border: 1px solid red;
overflow-y: auto;
}
<div class="top-bar">
</div>
<section>
<div class="component">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</section>
You mentioned in one of your comments that you're using Angular - you should update the question to include that and add it as a tag.
You can use window.innerHeight to get the pixel height of the current view.
If you have a singleton service in your Angular application where you're maintaining state, you can use a Behavior Subject to store that value so you can observe it in your components:
ie: state.service.ts
import { Observable, Subject, BehaviorSubject } from 'rxjs';
// Observable number sources
private currentWindowHeightStore = new BehaviorSubject<number>(0);
// Observable number streams
public currentWindowHeight$ = this.currentWindowHeightStore.asObservable();
// Service message commands
public setCurrentWindowHeight(WindowHeight: number) {
this.currentWindowHeightStore.next(WindowHeight);
}
Then in your component, define variables to store the windowSize, and if you're using pageable content (a list of items), a variable to store the pageSize:
private windowSize: number;
private pageSize: number;
In ngOnInit in your component, subscribe to the state.service Observable, and set the windowSize and pageSize based on the total window size, less any space required for navigation etc. (I've used sample values here, you'll want to set them according to your own layouts)
this.stateSvc.currentWindowHeight$
.subscribe(
(windowSize => {
this.windowSize = windowSize;
this.pageSize = Math.round((this.windowSize - 200) / 30) - 2;
this.cvPaging.pageSize = this.pageSize;
this.flex.refresh(true);
// 200 is the total size of the navigation header if you have one
// 30 is the size of a single row in the grid
// Total window size - minus total navigation / divided by the row height gives us the number of rows
// that will fit on the current screen size and we set the paging parameter to that value - 2 rows
}))
Now you have a windowSize variable that will update whenever the browser window changes size, and a pageSize variable that you can use if you're paging long lists to know how many items will fit in the window at it's current size.
You can use the windowSize variable to set the height of your container div with ngStyle:
<div [ngStyle]="{'height': 'auto','max-height':windowSize}>
Your content here.
</div>
The style property you are looking for is max-height. You can set this on your div and it will keep it from ever growing larger than that.
One trick for viewing this max-height in the event that you currently don't have enough content to fill it to maximum is to set the height equal to the max-height (temporarily) and to also temporarily give yourself a border on the div. This will allow you to visualize just how big that div can get.
EDIT: Different approach... (With fiddle example):
html, body {
height: 100%;
overflow: hidden;
}
Then, make the height of your main div a percentage, 100% will make it absolutely to the bottom, you may not like the look of this so try 95%, add overflow: auto; to get a scrollbar whenever the height is greater than the container it is in.
See Fiddle Example
I'm looking for a better to a solution to the problem of not having enough content to fill the screen.
Usually, if you want to fill the screen you either make the HTML, body heights 100% and then your container 100% or just use 100vh like in my JSFiddle below.
The problem is if the content does eventually stretch past 100% height of the screen it gets cut off.
I was wondering if there was a way (maybe with flexbox) where you could have 100% height but also if the content goes past 100% the container expands in size.
html, body
{
padding: 0;
margin: 0;
}
.content
{
background: grey;
/* height: 100vh; - this works but if content goes past 100vh it gets cut off */
}
<div class="content">
<span>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</span>
</div>
Use a container around the content to which you apply 100vh and display: flexand now the content can be made a column flexbox - see demo below and updated fiddle:
html,
body {
padding: 0;
margin: 0;
}
.wrapper {
min-height: 100vh;
display: flex;
}
.content {
background: grey;
display: flex;
flex-direction: column;
}
<div class="wrapper">
<div class="content">
<div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>
</div>
You are just missing the overflow: auto; in your .content div
Your Fiddle updated
body {
padding: 0;
margin: 0;
height: 100%;
}
.content {
background: grey;
height: 100%;
overflow: auto;
}
I have in some div long text and I would like to display only 3 lines from the text and when somebody click on the "read more", the whole text should be shown.
How to make this "read more" option in html/css?
One method would be to set the div's height to be three times its line-height, and set overflow: hidden.
You can then change its height to "auto" in the event handler for displaying the rest of the content:
document.querySelector('button').addEventListener('click', function() {
document.querySelector('#content').style.height= 'auto';
this.style.display= 'none';
});
body {
font: 14px verdana;
}
#content {
overflow: hidden;
height: 3.6em;
line-height: 1.2em;
width: 200px;
}
<div id="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<button>Read more</button>
You could also do this completely in CSS by using an adjacent sibling selector:
body {
font: 14px verdana;
}
#content {
overflow: hidden;
height: 3.6em;
line-height: 1.2em;
width: 200px;
}
#more:checked + div {
height: auto;
}
<label>
<input id="more" type="checkbox">Read more
<div id="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</label>
You can do this by first setting the height of the box to a specific size and keep the overflow hidden. Then use a button and js event to handle this .
<div id = "content">
your test will come here.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
<button type="button"
onclick ="document.getElementById('content').style.height='auto'">
Read more
</button>
</div>
Your css file should contain this.
#content {
overflow: hidden;
height: 3em;
line-height: 1em;
}
I was looking for read-more-possibility made only by html and css, too. The best idea for me was that with the adjacent sibling selector.
I changed what you read above in a certain way. First there is normal text. That stops at a senseful point, not counting the lines. Sometimes it can be one line, sometimes 4. After that I can expand it.
In css I wrote the first part, the second in html
body {
font: 20px verdana;
}
.content {
overflow: hidden;
height: 0em;
line-height: 1.2em;
width: 100%;
}
.more:checked + div {
height: auto;
}
<label>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<br>
Read more? Click at the box. <input class="more" type="checkbox">
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<br>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</label>