Struggling to make a simple box - html

I'm new to webdev using html/css. Starting to learn, and I want to create a really simple thing.
Basically a responsive fixed box that never touches the viewport by 20px.
If you change the screen size, the box will always have a 20px margin, top, sides and bottom. I don't want scrolling at all!
Then at the center, I want to place a .gif that is about 40em that scales according to screen size.
My problems until now, is that I can't make that box at all, I've tried dozens and dozens of different solutions I've lost track of which ones, I've got 30 tabs opened with tutorials but none solve my problem.
Every try there is always a scrollbar, or the box has margins on top/left, but not bottom/right, or the gif is centered horizontally but not vertically, or there are margins but I can't control size of them....
Is this so hard? It would be awesome to have some directions, thank you!
This is what I currently have, but it's just one of the dozens of my failed attempts. (i didn't include the .gif)
body {
background: #f0e8e6;
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
}
div {
width: 90vw;
height: 90vh;
padding-top: 100px;
padding-bottom: 100px;
padding-left: 100px;
padding-right: 100px;
position: center;
top: 50%;
left: 50%;
background: #ffffff;
text-align: center;
overflow: hidden;
}
<div>
</div>

This is a little bit of an odd way to go about it, but honestly I really enjoy this method as it has very easy to understand logic behind it. Apply the margin to the parent element via padding, not the child element.
body {
background: #f0e8e6;
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
padding: 0;
margin: 0;
width: 100vw;
height: 100vh;
padding: 20px;
box-sizing: border-box;
}
div {
width: 100%;
height: 100%;
background: #ffffff;
text-align: center;
overflow: hidden;
}
Firstly, you need to remove the default padding/margin inbuilt into the body. Once you do that, you add the padding to the body - this gives the 20px margin. Finally, you need to ensure that the body spans the width of the page, and the div spans the width of the body. This is achieved by their respective width/height properties.
A key property here is box-sizing. This honestly should be the default, but essentially it stops the container from growing when adding padding. If this wasn't here, the body will overflow the page.
To add the image in the center, you should be using flex. It's quite a big topic, but it works perfectly for these situations. Learn more about flex here, but for now below in an example. Note the align-items and justify-content properties, these are what align the image vertically and horizontally.
body {
background: #f0e8e6;
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
padding: 0;
margin: 0;
width: 100vw;
height: 100vh;
padding: 20px;
box-sizing: border-box;
}
div {
width: 100%;
height: 100%;
background: #ffffff;
text-align: center;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>loiz</title>
<link rel="stylesheet" type="text/css" href="styling.css" media=”screen” />
</head>
<body>
<div>
<img src="https://via.placeholder.com/150C/O"/>
</div>
</body>
</html>
Note that the top and left css attributes only apply to elements with absolute or fixed positioning (see here).
Also, position: center is not a valid value. Check here for valid values.

One approach:
/* Using CSS custom properties to define
the known, repeated measurement: */
:root {
--margin: 20px;
}
/* setting the elements to all use the
same box-sizing method, use the same
font, margin and padding: */
*,
::before,
::after {
box-sizing: border-box;
font: normal 1rem / 1.5 sans-serif;
margin: 0;
padding: 0;
}
body {
/* removed the properties that don't apply
in the demo; using a background-color
to visualise the sizing and layout: */
background-color: white;
}
div {
/* display: flex allows us to more easily
position the contents
vertically/horizontally: */
display: flex;
/* using the calc function to calculate the
space left over from subtracting 2 * 20px
from 100vw (viewport-width units) to
calculate the width, and from 100vw
(viewport-height units) to get the height: */
width: calc(100vw - 2 * var(--margin));
height: calc(100vh - 2 * var(--margin));
/* applying the margin around the <div>: */
margin: var(--margin);
/* to easily visualise the layout: */
background-color: red;
}
div img {
/* to easily position the <img> in the
horizontal and vertical centre: */
margin: auto;
/* setting the width leaves the browser
to set the height appropriately to
maintain the aspect-ratio: */
width: 40vw;
}
<div>
<img src="https://via.placeholder.com/300.gif/09f/fff" alt="Placeholder gif">
</div>
References:
box-sizing.
calc().
display.
font short-hand.
margin.
Values and Units.

you have to use media queries for making it responsive for other devices , while provide a padding of 2% to the outermost div and then give and then place your gif in that div and provide that gif a padding also and you will get your required result

Here's an idea of how to accomplish this:
body {
background: red;
padding: 0;
margin: 0;
display: flex;
height: 100vh;
}
div {
width: calc(100vw - 40px);
height: calc(100vh - 40px);
background: #ffffff;
overflow: hidden;
margin: auto;
display: flex;
}
img {
width: 40vw;
margin: auto;
}
<div>
<img src="https://images.pexels.com/photos/10262654/pexels-photo-10262654.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"/>
</div>

There are some default padding and margin on body tag. You need to reset them first. Also html tag is not full height by default as well. You also need to make them fullscreen by adding width: 100% and height: 100%
And then you can resize your div correctly. You can use calc method in css. In your case; width: calc(100% - 240px) 240px is 200px padding (100px each) for both sides and 40px margin (20px each).
To center gif for you can use flex features rather than using text-align etc.
:root {
--margin: 20px;
--padding: 100px;
}
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
background: #f0e8e6;
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
}
div {
width: calc(100% - (var(--margin) * 2) - (var(--padding) * 2));
height: calc(100% - (var(--margin) * 2) - (var(--padding) * 2));
padding: var(--padding);
background: #ffffff;
overflow: hidden;
position: relative;
display: flex;
align-items: center;
justify-content: center;
left: var(--margin);
top: var(--margin);
}
<div>
<img src="https://media0.giphy.com/media/WXZ5DqIOhQrxtkcszN/giphy.gif?cid=ecf05e47yzd9cgsu3pzebujrmdl3od4erxhdtwozizzjx2nc&rid=giphy.gif&ct=g" alt="Hell Yeah Snl GIF by Saturday Night Live" style="width: 500px; height: 280px; ">
</div>

Related

How can I make a resizable flex item retain its aspect ratio?

I have an effect on my website, and it only works within a 16:9 aspect ratio. This means I need to keep it within that aspect ratio. I wanted to make a box that was vertically and horizontally centered which could resize proportionally to contain the effect. I looked up many tutorials and guides on flex resizing, but i still cant get it to work properly. The padding in the that contains the box is lopsided, and it doesnt align properly either. It scrolls horizontally even though im using 100vh/vw?? Does 100% of the viewport's height really mean what it says?
I'm really not sure what to do...
Codepen example of my code below:
https://codepen.io/Ktashi/pen/KKeOJey
html
<div class="flex-align">
<div class="aspect-ratio-box"></div>
</div>
css
body {
padding: 0;
margin: 0;
}
.flex-align {
width: 100vw;
height: 100vh;
margin: 0;
padding: 1vw;
display: flex;
align-items: center;
justify-content: center;
}
.aspect-ratio-box {
height: auto;
aspect-ratio: 16/9;
background: red;
flex-grow: 1;
flex-shrink: 1;
flex-basis: 94vw;
max-height: 94vw;
max-width: 94vw;
}
I tried changing the flex-grow: property's value, along with flex-shrink: and flex-basis: but that didn't help much. I'm very stuck as I've only really been coding with html and css for about a year off and on.
You can use the CSS media query to test whether the item will fit within the parent which has 100vw/100vh dimensions.
This snippet is just to give the idea.
It does a couple of things - makes the parent's padding be part of its dimensions by setting box-sizing border-box and sets the height or width as % of the parent dimensions.
.aspect-ratio-box {
aspect-ratio: 16/9;
background: red;
}
#media (max-aspect-ratio: 16 / 9) {
.aspect-ratio-box {
width: 94%;
}
}
#media (min-aspect-ratio: 16 / 9) {
.aspect-ratio-box {
height: 94%;
}
}
body {
padding: 0;
margin: 0;
background: black;
}
.flex-align {
background: blue;
width: 100vw;
height: 100vh;
margin: 0;
padding: 1vw;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
<div class="flex-align">
<div class="aspect-ratio-box"></div>
</div>

How can I use "object-fit: contain" in CSS and still have a border radius on the image?

I'm trying to show an image in a "lightbox" style so that it will fill the available area on screen, in this case 90% of the width of the page and 70% of the height.
Using object-fit: contain; seems to be the de facto way to do that but it's not quite working with border-radius. Is it possible to use object-fit on an <img> and still have the border radius applied as intended?
You'll need to resize your browser window to see what happens when you run the below snippet. I've got the same code running in JSFiddle, as per the below video.
div {
margin: auto;
width: 90vw;
height: 70vh;
background-color: DeepSkyBlue;
}
img {
width: 100%;
height: 100%;
object-fit: contain;
border-radius: 50px;
background-color: Crimson;
}
<div>
<img src="https://images.freeimages.com/images/large-previews/773/koldalen-4-1384902.jpg">
</div>
Contain isn't really helping here.
Instead, set the max width and height of the img to 100%. The system will fit it in either totally top to bottom or side to side, but the img element will have whatever dimensions it needs so the border radius will work on it OK.
To center the img, if that is what you want, you can display: flex the parent div and justify/align items to the center.
div {
margin: auto auto;
width: 90vw;
height: 70vh;
display: flex;
justify-content: center;
align-items: center;
background-color: DeepSkyBlue;
}
img {
max-width: 100%;
max-height: 100%;
border-radius: 50px;
background-color: Crimson;
}
<div>
<img src="https://images.freeimages.com/images/large-previews/773/koldalen-4-1384902.jpg">
</div>
As commented, setting max-width and max-height seems to be what you need or expect:
div {
margin: auto;
width: 90vw;
height: 70vh;
display:grid;
background-color: DeepSkyBlue;
}
img {
max-width: 100%;
max-height: 100%;
margin:auto;/* x,y center if inside a grid or flex box */
object-fit: contain;/* useless by now, img should keep its ratio */
border-radius: 50px;
border-radius: calc( 5vw + 5vh); /* will scale, maybe you find this usefull */
background-color: Crimson;
}
<div>
<img src="https://images.freeimages.com/images/large-previews/773/koldalen-4-1384902.jpg">
</div>
Use object-fit: cover; instead of contain

Get rid of whitespace at bottom of Mat Dialog

I am using Angular Material for my Angular app. Currently, I have a dialog that shows info about a post. However, there is a lot of annoying whitespace at the bottom of the dialog that I want to get rid of. How can I do this?
Here is an image:
HTML
<div id="postModal">
<div mat-dialog-content id="postForm">
<div class="bigImage">
<img src={{imageLinks[0]}} class="postImage"/>
</div>
</div>
</div>
SCSS
body{
position: relative;
}
.postImage{
height: 80%;
width: 100%;
}
.bigImage{
text-align: center;
display: block;
}
#postForm{
height: 80vh;
width: 100%;
display: box;
}
mat-dialog-container{
padding-right: 30px;
padding-left: 30px;
padding-top: 10px !important;
padding-bottom: 0px !important;
}
You should remove the height from the #postForm. A height: 80vh makes it take up 80% of the height of the screen.
Since you are providing a fixed height to it, there will be empty space left if the image doesn't take up all the space.
Also your postImage has a height of 80%, the remaining space will be empty.
body{
position: relative;
}
.postImage{
/* height: 80%; this is your bug */
width: 100%;
}
.bigImage{ /* you don't need this level and even if use <figure></figure> not <div></div> */
text-align: center; /* this means empty space on sides when text is to short to fill, this class hasn't setted width, so it should adjust to content witch is an img - block element without any wraps */
display: block;
}
#postForm{
height: 80vh; /* this one may caused problems too */
width: 100%;
display: box; /* incorrect value */
}
mat-dialog-container{
/* padding-right: 30px; */
/* padding-left: 30px; */
/* padding-top: 10px !important; don't use !important instead of debugging */
/* padding-bottom: 0px !important; */
padding: 10px 30px 0; /* nice and readable instead of 4 lines */
}
If you set strict height value don't be surprised if it keep it. Good prepared css is an investment - works properly and maintaining is plasure without headaches.
.postImage{
height: auto; or 100%
width: 100%;
}
or don't give the height at all

How to extend a div to fill the whole page

I am building a page with two columns side-by-side that should fill the entire page. Both columns should both be 50% of the available width with no margin or padding on either side and take up 100% of the available height depending on the resolution.
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
body>* {
flex-shrink: 0;
}
.login-column {
float: left;
width: 50%;
background-color: #F4F6F9;
margin: 0;
}
.news-column {
float: left;
width: 50%;
background-color: #75BFF0;
/* For browsers that do not support gradients */
background-image: linear-gradient(to bottom right, #75BFF0, #C9E7FF);
/* Standard syntax (must be last) */
margin: 0;
flex-grow: 1;
}
<div class="row">
<div class="login-column">
<h1>Login</h1>
</div>
<div class="news-column">
<h1>News</h1>
</div>
</div>
Currently, the divs have no padding or margin on the top, left, and right; however, the background color only extends to the end of the text. I want the background to extend to the bottom of the page, without a scrollbar.
On a side note, I am using divs. Is this still recommended or should I be using the new, HTML5 things such as article, aside, .etc?
In order to get a DIV to fill the page in height you need to use this :
CSS
div {
height: 100vh;}
Also everything is explained in this post :
How to make a div 100% height of the browser window
remove floats, you can add height to your columns 100vh but in your head section of the page should be <meta name="viewport" content="width=device-width, initial-scale=1">
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
body>* {
flex-shrink: 0;
}
.row {
display: flex;
}
.login-column {
flex: 0 0 50%;
background-color: #F4F6F9;
margin: 0;
height: 100vh;
}
.news-column {
flex: 0 0 50%;
background-color: #75BFF0;
/* For browsers that do not support gradients */
background-image: linear-gradient(to bottom right, #75BFF0, #C9E7FF);
/* Standard syntax (must be last) */
margin: 0;
height: 100vh;
}
<div class="row">
<div class="login-column">
<h1>Login</h1>
</div>
<div class="news-column">
<h1>News</h1>
</div>
</div>
You can simply include height in div classes.
.login-column {height: 100%;}
.login-column {height: 100%;}
You shouldn't use floats and position: absolute, unless you absolutely know what you're doing. I suggest using a flex container to do what you want, and use max-height to make the two columns (sections) fill out the whole screen height. If you just use height: 100vh, the columns will stay at that height blocking things from overflowing.
Also note how I use class syntax to reuse CSS code.
body {
margin: 0;
padding: 0;
}
.flex-container {
width: 100%;
display: flex;
}
section {
min-height: 100vh;
flex-basis: 50%;
box-sizing: border-box; /* To let padding be part of the width */
padding: 1rem;
}
section.left {
background-color: #F4F6F9;
}
section.right {
background-image: linear-gradient(to bottom right, #75BFF0, #C9E7FF);
}
<body>
<div class="flex-container">
<section class="left column">
Ladidaa
</section>
<section class="right column">
Tralalaa
</section>
</div>
</body>
Did you try to create a content div that contains the columns, i would try something like this.
* {
padding: 0;
margin: 0;
}
body, html {
height: 100%;
}
.columns-container {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.login-column {
display: flex
background-color: #F4F6F9;
margin: 0;
width: 50%;
}
.news-column {
display:flex;
background-color: blue;
margin: 0;
width: 50%;
height: 100%;
}
<div class="columns-container ">
<div class="login-column">
<h1>Login</h1>
</div>
<div class="news-column">
<h1>News</h1>
</div>
</div>
Regarding use of div, article and aside, actually they are used for to code semantic Html to get the best result for Search Engine Optimization and other bots related activity also good for other developers to understand code flow. Not answering your primary question as it already answered many times, let me know if you are not satisfied with other answers :)
Note: Using div is all fine in your case, don’t worry.

CSS challenge: Two background images, centered column with fixed with, min-height 100%

In a nutshell
I need a CSS solution for the following requirements:
Two vertically repeated background images, one aligned to the left, one aligned to the right
One centered column on top with fixed width and a minimum height of 100%
Cross browser compatibility
A little more details
Today a new requirement for my current web site project came up: A background image with gradients on the left and right side (replaces the current body background image). The challenge is now to specify two different background images while keeping the rest of the layout spec. Unfortunately the (simple) layout somehow doesn't go with the two backgrounds.
My layout is basically one centered column with fixed width:
#main_container {
background-color: white;
margin: 0 auto;
min-height: 100%;
width: 800px;
}
Furthermore it's necessary to stretch the column to a minimum height of 100%, since there are quite some pages with only little content. The following CSS styles take care of that:
html {
height: 100%;
}
body {
background-image: url('old-background.png');
margin: 0;
height: 100%;
padding: 0;
}
So far so good - until the new body background image with gradients arrived. I tried the following solutions
Two absolute positioned divs behind the main container
One image defined with the body, one with the html CSS class
One image defined with the body, the other one with a large div begind the main container
With either one of them, the dynamic height solution was ruined. Either the main container didn't stretch to 100% when it was too small, or the background remained at 100% when the content was actually longer
Modified:
<body>
<div class="container"><div>
<div id="main_content"></div>
</body>
With css:
html {
height: 100%;
}
body {
background: url(left.png) repeat-y top left;
background-attachment:fixed;
height: 100%;
margin: 0;
padding: 0;
}
div.container {
background: url(right.png) repeat-y top right;
height: 100%;
width: 100%;
position:fixed; /* This won't work in all browsers. May need a JS solution for IE6 */
}
#main_content {
height: 100%;
width: 800px;
margin: 0 auto;
background-color: white;
}
Edit:
This version works for browsers that support position:fixed (not ie6).
Example page: http://jsbin.com/ebozi3/4/edit
Using a "layout table", my issue can be solved. A pure CSS solution, however, would be preferred!
Here's a working table-based solution:
table.layout {
border-collapse: collapse;
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
table.layout td {
margin: 0;
padding: 0;
vertical-align: top;
}
td.layout_left {
background-image: url('background-left.png');
background-position: top left;
background-repeat: repeat-y;
}
td.layout_center {
background-color: white;
width: 800px;
}
td.layout_right {
background-image: url('background-right.png');
background-position: top right;
background-repeat: repeat-y;
}
And the HTML code:
<table class="layout">
<tr>
<td class="layout_left"> </td>
<td class="layout_center">
<!-- content -->
</td>
<td class="layout_right"> </td>
</tr>
</table>
[revamp]
I'm silly. Very.
Problem: body needs to have bg images, #main_container needs to have 800 width and in the center.
(Lousy approach: I was doing #main_container with bg images, not centered, 800px.)
New approach: I suggest a div inside body and a span inside that new div:
<body>
<div>
<span>
<div id="main_container">
Regular contents.
</div>
</span>
</div>
</body>
Then:
body {
background: url(img/bg_left.gif) repeat-y top left;
}
body>div {
background: url(img/bg_right.gif) repeat-y top right;
}
body>div: {
text-align: center;
}
body>div>span {
display: inline-block;
/* IE only likes this rule on elements that are inline by nature, thus the use of span.
I'm not sure 100% height will work on #main_container. */
}
And your regular rules:
#main_container {
background-color: white;
margin: 0 auto;
min-height: 100%;
width: 800px;
}