CSS, Idiom for Preferred min width - html

I have learned from similar questions that min-width always beats max-width, which is unfortunate, because I think modern websites mostly require it the other way around.
I often have to resort to media queries to solve the below problem, but hoping there is an elegant/better solution:
Say I have a div:
<div>Words on a page. Words on a page. Words on a page. Words on a page.</div>
I often wish to have this div width to be at least 500px, as long as it's not bigger than 90% of the screen width. This can be accomplished with:
div {
min-width: 500px;
max-width: 90vw;
}
Now the problem with the above is it overflows on mobile.
I encounter this all time when I have a list of objects, and say the items are deletable, then if one deletes the widest element, the whole design jumps as it resizes. To minimize this effect, I wish to have a default width and allow it to expand in rare cases as needed.

Do it like below:
div {
min-width: min(500px, 100%); /* will take less than 500px if there is an overflow */
max-width: 90vw;
border:1px solid;
}
<div>Words on a page. Words on a page. Words on a page. Words on a page.</div>

Are you looking to set the min-width to no more than 90% of the width of the screen but if the screen is wide enough then 500px.
If so maybe try:
div {
min-width: min(500px, 90vw);
display: inline-block;
background-color: lime;
}
<div>Some text </div>

Related

automatically decrease container width while resizing broswer window

I am using CSS and HTML trying to reproduce the homepage of this website http://www.newsweek.com/ as an exercise.
If you open the page with a large screen you will see at both sides two empty columns that gradually decreases as the broswer width is reduced.
I want to reproduce this behaviour but can't make it until the end: I have set a container class with initial width 80% that become 100% at some point thanks to media query in CSS:
#media screen and (max-width: 1047px) {
.container {
width:100%;}}
What I miss is the gradually reduction of this container. How it can be made?
Thank you very much
For an experience like that, all you need is something like this:
.container {
max-width: 1200px;
margin-right: auto;
margin-left: auto;
}
If .container is applied to a block level element (like <div>) then this element naturally goes to be as wide as it can. This just says don't go wider than 1200px, and designate the left over space equally between the left and the right.
If for some reason the element is not block level (e.g. a <span>) then simply add display: block; to the above code to make it block level.

Responsive layouts with min-width, width%, no easy way to avoid gaps?

I have a simple responsive webpage that can run in two columns, with css for each div being
.half {
width: 45%;
min-width: 300px;
float: left;
}
For wide screens each div column gets half the width, for narrower screens the columns compress until they reach 300px, and then they wrap. Basically works OK.
However, when the screen is 400px wide (say) the columns are still compressed to 300px. (Because half of 400px is 200px, so min-width of 300px takes priority. But in this case I would want it to be the full 400px as there are no other columns to its right.)
Is there a easy way to stop that?
There are new flex-box options, but I need to run on the public web, lots of browsers and phones. Something that polishes for newer and works for older is OK. I do not want to add JavaScript just to do this.
I think that the answer is a simple NO, not possible. But I would appreciate confirmation that I have not missed something.
(There are a number of similar questions already but none that I could find that address this simple case specifically.)
(Edited to address confusion in comments.)
I assume you are wanting to implement a media-query to specify new rules once a window is less than a specific width. Therefore, you could do something like:
// Override styles for elements once the element is less than a specified width
#media only screen and (max-width: 400px) {
// If window is less than 400px, apply new styles. ie: width takes full width
.half {
width: 100%;
}
}
Which will make the .half class 100% width once the device/window is 400px or less.
Example of media-query provided by misterManSam: JS Bin
As per my understanding you need like this:
.half {
width: 100%;
min-width: 300px;
max-width: 500px;/*define max-width as you wish*/
float: left;
}

Why does vw include the scrollbar as part of the viewport?

I'm trying to build a website that has lots of boxes that are of equal width and height. For example, I have a page that has 2 equal size boxes side by side.
The simple solution was to set the width and height to 50vw. This works great until there is a scroll bar. I've Googled around for hours and can't understand why on earth vw and vh would include the scrollbars as part of the viewport.
Here's a sample of my issue
HTML
<div class="container">
<div class="box red"></div>
<div class="box green"></div>
</div>
<div class="lotta-content"></div>
CSS
body {
margin: 0;
padding: 0;
}
.container {
width: 100vw;
}
.box {
float: left;
width: 50vw;
height: 50vw;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.lotta-content {
height: 10000px;
}
Notice the unwanted horizontal scrollbar
https://jsfiddle.net/3z887swo/
One possible solution would be to use percentages for the widths, but vw for the height, but it won't ever be a perfect box which isn't the worst thing in the world, but still not ideal. Here's a sample
https://jsfiddle.net/3z887swo/1/
Does anyone know why vw/vh include scrollbars as part of the viewport? Also, if someone has a better solution than my own, I'd love to hear it. I'm looking for a pure CSS solution. I rather not have javascript.
I have a different answer, and feel the need to share my frustration
BECAUSE STANDARD-MAKERS ARE STUPID
(committees, in general, always are)
One simple (simplicistic) workaround is keeping the scrollbar always around and be dealt with it
html,body {margin:0;padding:0}
html{overflow-y:scroll}
(use overflow-x for a layout that uses vh)
I believe they seriously screwed the pooch on this one.
It would be convenient if viewport units didn't include cause scrollbars but it is the display size (screen) after all. Have look at this solution with a pseudo element though:
http://www.mademyday.de/css-height-equals-width-with-pure-css.html
Makes for a square in your example as well:
https://jsfiddle.net/3z887swo/4/
.box {
float: left;
width: 50%;
}
.box::before {
content: "";
display: block;
padding-top: 100%;
}
Edit - if anyone is wondering why this works (vertical padding responding to the original element's width)... that's basically how it's defined in the specification:
The percentage is calculated with respect to the width of the generated box's containing block, even for 'padding-top' and 'padding-bottom'.
http://www.w3.org/TR/CSS2/box.html#padding-properties
After coming across my own answer, I think it needed some refinement. Semantic ambiguity is why I replaced the word "include" with "cause" at the top. Because it's more the fact that vw units only take the viewport size into account - not including any scrollbar and causing overflow and a scrollbar in the other direction when its width is added to 100vw (making the total space that is needed the viewport plus scrollbar width, exceeding the screen).
As with the question here, the best way to handle vw units is likely to avoid them if you can because they just aren't very compatible with desktop browser (that don't have overlaying scrollbars).
I edited out the idea that included a CSS variable, however hopeful it seemed.
html { overflow-x: hidden; }
seems to work
This question is old, and answered well above, so I'm going to focus on obtaining scrollbar width to then be used to calc element widths, as that's why I landed here. Hopefully this will help other Googlers.
A sloppy CSS solution
I started writing the pure CSS solution based on the calculation below but once you start factoring in elements inside variable width containers, especially when they aren't 100% of the visible width, the calc functions start getting convoluted and unreadable.
For anybody interested, this calc on the root element (<html>) (assuming the doc is full width and no wider) will give you the scrollbar width or 0 when no scrollbar is displayed.
calc( 100vw - 100% );
A robust solution
Personally, I wouldn't battle CSS on this one. Use the right tool for the job:
(function get_scrollbar_width() {
// Get window width including scrollbar.
const withScrollBar = window.innerWidth;
// Get window width excluding scrollbar.
const noScrollBar = document.querySelector("html").getBoundingClientRect().width;
// Calc the scrollbar width.
scrollbarWidth = parseInt((withScrollBar - noScrollBar), 10) + 'px';
// Update the CSS custom property value.
let root = document.documentElement;
root.style.setProperty('--scrollbar', scrollbarWidth);
})();
:root {
--scrollbar: 0px;
}
body {
overflow: scroll;
}
.demobox {
display: grid;
grid: auto / var(--scrollbar) max-content;
width: calc(10em + var(--scrollbar) );
margin: 0 auto;
}
.demobox > div {
background: red;
}
.demobox > p {
padding: 1em;
text-align: center;
width: 10em;
}
<div class="demobox">
<div></div>
<p>
This red grid cell represents the scrollbar width as set
on the CSS custom property by the JavaScript function.
</p>
</div>
I have a solution here. It'll include the scrollbar width when you use 100vw, right? so if we can't make it right, then we can remove the scrollbar, make it invisible. like this: Hide scroll bar, but while still being able to scroll

How to give general maximum to a html-site completely based on css with vw-units?

I built a site where nearly every element got it's size in vw-units. So text, padding, margin, height and width of every element is set in "vw". This works great.
My problem is that there should be a change and now the site should not scale over 1200px-width any more. That means if the screen is wider than 1200px the site should not fill 100% of the width and every element should be as big as it would be on 1200px screen width.
For sure I have a div with a max-width of 1200px but everything inside is still growing with the screen.
I know that I can use 1200px as a breakpoint and that I can define every element again beyond that. But that is what I want to avoid.
My question means: Is there any way to modify the css-unit "vw" in the way that it uses 1200px as base-width for every wider screen than that?
If you're uing a container element, you can set it's max-width, which will not allow the width of the element to exceed the amount you specified.
html, body {
height: 100%;
}
body {
background-color: #faa;
width: 100%;
margin: 0;
padding: 10px;
box-sizing: border-box;
}
#container {
background-color: #afa;
width: 60vw;
max-width: 200px;
margin: 0 auto;
padding: 10px;
}
#container p {
margin: 0;
}
<div id="container">
<p>This div's width can't go any further than 200 pixels.</p>
</div>
I found your question after having solved the same exact problem, and then wondering if there was a different solution. It seems like it’s a common issue right?
Unfortunately, my solution probably won’t work for any one since I have a very dynamic site where almost all my CSS dimensions get put through a function at runtime. Therefore it is able to modify it for exactly this situation. It works for what I’m doing but I can hardly recommended as a good practice.
The only other solution I could think of is to multiply everything by a sort of fake VW unit.
.dog-image
{
// 50vw
width: calc(50 * min(1vw, 12px));
}
So when the screen is wider than 1200px then it is limited to 50 * 12px.
I haven’t actually tested this so I don’t know if there are any rounding errors. An alternative approach should fix that.
width: min(50vw, calc(50 * 12px));
If you’re using a css preprocessor you could probably make a function to do this for you.

How to limit a content DIV height to its container height, with percentage?

I've the following part of HTML structure (closing tags omitted for simplicity, indentation represents nested tags):
...
- <div class="main-content-wrapper">
- <div class="item-image-wrapper">
- <img class="item-image fit">
- <div class="item-text">
- <h2 id="itemTitle">
- <p id="itemContent">
with the following CSS
.itemdetailpage section[role=main] article .main-content-wrapper {
display: -ms-grid;
-ms-grid-rows: auto auto;
width: 100%;
height: 100%;
}
.itemdetailpage section[role=main] article .item-image-wrapper {
-ms-grid-row: 1;
width: 100%;
height: 100%;
}
.itemdetailpage section[role=main] article .item-image {
margin-top: 0px;
margin-left: 0px;
}
.itemdetailpage section[role=main] article .item-image.fit {
/* Fit image to page size */
max-width: 100%;
max-height: 100%;
}
.itemdetailpage section[role=main] article .item-text {
-ms-grid-row: 2;
margin-right: 5px;
}
The goal is to have the IMG no taller (and no wider) than the main content allows, i.e. to fit the main content space if bigger than that, or to stay at its original size if smaller. The text can just flow below the image, and so can also go below the fold, no problem with that. This should happen with no JS code, CSS only.
When the item text is narrower than the image, it's all ok. The image wrapper is some pixels taller than the image, don't know why, but it looks ok.
The problem I see here is when, at the same time: the image is taller than the available height, and the item text is wider than the image (the item title, in particular). In this case the image wrapper gets taller than its container, and so follows the image. E.g. .main-content-wrapper receives a (correct) height of 900px, but item-image-wrapper is 1024px tall and image is 1024px tall (its natural height).
I know this 100% DIV height has come again and again, and I've looked for answers, but I was not able to find one suitable for this case.
EDIT:
I've found this SitePoint reference, the paragraph where it says "Percentage values refer to the height of ...": does anyone know anything about this rule?
One thing you can do to achieve this in certain situations is add width: 100% and height: 100% to every intervening element, and rely on the text extending out of its containing block if the image takes up all of the available space. This won't work in every situation because it's then very hard to get anything else on the page to make room for the extending text, but on a vanilla HTML page containing nothing else it works, and it might be possible to make it work in some other situations by putting a floated element at the end of the text content and putting a clearing element in any spot that needs to come after that text content, as in this jsFiddle: http://jsfiddle.net/t6LvY/2/
As the design accumulates complexity this could get nasty fast, however. You're probably better off just going with a bit of JavaScript to set the max-height of the image to the window height on window resize.
I think you should remove max-height from image class max-width:100% is enough to fit that image to parent container of image. I don't know this will help you or not.
My own proposed (sad) answer: if I want to keep percentage heights on the DIVs, and stick to pure CSS (i.e. no JS), then the goal cannot be accomplished.
The W3C specs says that the percentage in this case is basically ignored (look for text "The percentage is calculated with..."). And also Internet Explorer docs (the browser I'm working with) says basically the same (look for text "* If the height of the containing block...*").