How to make adaptive centered div? - css

What I have now:
display: flex;
align-items: center;
flex-direction: column;
How it looks with error:
What's the target:
I can do it with
margin-left: *X*px, but it is not the way I want to solve it.
May I do it with some flex properties ?
It is important to do it without bootstrap and grid.

This could be a possible solution: Center the box with flexbox and display the errors with position: absolute;. You need to take care of responsive optimization if you want to use it on a wider range of devices.
* {
box-sizing: border-box;
}
.container {
display: flex;
align-items: center;
justify-content: center;
}
.box {
border: 1px solid black;
padding: 10px;
width: 400px;
}
.field {
position: relative;
}
.input {
margin-bottom: 10px;
width: 100%;
}
.error {
position: absolute;
left: 105%;
top: 0;
width: 200px;
}
<div class="container">
<div class="box">
<div class="field">
<input class="input" type="text">
<div class="error">error 1</div>
</div>
<div class="field">
<input class="input" type="text">
<div class="error">error 2</div>
</div>
<button>Send</button>
</div>
</div>

Related

ngFor Elements in Row

Hello currently I'm trying to display my items from ngFor in a row, but it's not working.
My Code:
<ng-container>
<div class="model" *ngFor="let model of modelService;" >
<div id="Ppicture" > {{model.modelPic}} </div>
<div id="Name" > {{model.modelName}} </div>
<div id="Age"> {{model.modelAge}} </div>
</div>
</ng-container>
CSS:
ng-container{
display: flex;
flex-direction: row;
}
.model{
padding-left: 10px;
padding-top: 10px;
border: solid 1px;
height: 150px;
width: 150px;
justify-content: center;
text-align: center;
}
I also tried to put display flex into the .model class, but flex is only putting the text in a row, not the boxes.
That's how it looks like
https://ibb.co/VLSKVcS
try to put width: 100% in ng-container.
ng-container{
width: 100%;
display: flex;
flex-direction: row;
}
Try this
<ng-container>
<div class="model_sec">
<div class="model" *ngFor="let model of modelService;" >
<div id="Ppicture" > {{model.modelPic}} </div>
<div id="Name" > {{model.modelName}} </div>
<div id="Age"> {{model.modelAge}} </div>
</div>
</div>
</ng-container>
ng-container {
display: block;
width: 100%;
}
.model {
padding-left: 10px;
padding-top: 10px;
border: solid 1px;
height: 150px;
width: 150px;
text-align: center;
}
.model_sec {
display: flex;
width: 100%
}

Positioning of elements in a flex layout [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I need help laying out my html with css flexbox (I hope this is doable with flexbox).
I have a Container with a variable amount of images. Image can be either landscape or portrait orientation. If image is landscape (Image 1) - it will occupy one 'row'. If image is portrait - there are two cases:
If there is one portrait image in a 'row' (either it's the last image, or the next one is landscape) - then Image 2 should be centered on the 'row'.
If there are two successive portrait images - I'd like them to both fit into one 'row'
Pls note, that the 'rows' are an abstract notion here. I don't want to use css grid (unless there are absolutely no other options).
Using a flexbox in combination with the justify-content: center; and flex-wrap: wrap; should achieve the exact effect you are looking for.
Please see the two code snippets below for the two examples. I have used multiple coloured div with a width and height to simulate the horizontal and vertical image types you referred to.
.flex {
display: flex;
flex-wrap: wrap;
width: 100px;
border: 2px black solid;
padding: 1em;
justify-content: center;
}
.horizontal {
background: yellow;
width: 100px;
height: 50px;
margin-bottom: 1em;
}
.vertical {
background: green;
width: 50px;
height: 100px;
}
<div class="flex">
<div class="horizontal">Image 1</div>
<div class="vertical">Image 2</div>
</div>
.flex {
display: flex;
flex-wrap: wrap;
width: 100px;
border: 2px black solid;
padding: 1em;
justify-content: center;
}
.horizontal {
background: yellow;
width: 100px;
height: 50px;
margin-bottom: 1em;
}
.vertical {
background: green;
width: 50px;
height: 100px;
}
#blue {
background: blue;
}
<div class="flex">
<div class="horizontal">Image 1</div>
<div class="vertical">Image 2</div>
<div class="vertical" id="blue">Image 3</div>
</div>
This can be done with align-items: center and flex-wrap:wrap:
.flex{
width: 220px;
display:flex;
align-items: center;
flex-wrap:wrap;
}
.flex img{
border: solid 4px #efefef;
box-sizing:border-box;
margin: 0 auto;
}
<h3>Example 1</h3>
<div class="flex">
<img src="https://placekitten.com/220/60">
<img src="https://placekitten.com/110/120">
</div>
<h3>Example 2</h3>
<div class="flex">
<img src="https://placekitten.com/220/60">
<img src="https://placekitten.com/100/120">
<img src="https://placekitten.com/100/120">
</div>
You can easily achieve this using the same grid system as Bootstrap using class like container, row, col:
.container {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.align-center {
align-items: center;
justify-content: center;
}
.image1 {
width: 500px;
height: 300px;
background-color: red;
}
.image2,
.image3 {
width: 250px;
height: 500px;
}
.image2 {
background-color: yellow;
}
.image3 {
background-color: blue;
}
.image1,
.image2,
.image3 {
border: solid #000 2px;
}
<div class="container align-center">
<div class="row">
<div class="col image1">
<h1>image1</h1>
</div>
</div>
<div class="row align-center">
<div class="col image2">
<h1>image2</h1>
</div>
</div>
</div>
<div class="container align-center">
<div class="row">
<div class="col image1">
<h1>image1</h1>
</div>
</div>
<div class="row align-center">
<div class="col image2">
<h1>image2</h1>
</div>
<div class="col image3">
<h1>image3</h1>
</div>
</div>
</div>

Scale images inside divs with text

For a personal project with Angular, Angular Material and Flex-Layout I am trying to achieve a similar layout used by Bring! App:
Having images of different size (not all squared) I would like to center them proportionally and allow some text under them.
I have the following template and scss styles:
<div fxLayout="row" fxLayoutGap="5px" class="cards-container">
<div class="item-card">
<div class="image">
<img src="../../../../assets/icons/apple.png" alt="Mela" />
</div>
<span class="item-name">Mela</span>
<span class="description">12</span>
</div>
<div class="item-card">
<div class="image">
<img src="../../../../assets/icons/milk.png" alt="Latte" />
</div>
<span class="item-name">Latte</span>
<span class="description">1 description comes here, must be hidden if long text</span>
</div>
</div>
//---------------------------------------------------
.cards-container {
flex-wrap: wrap;
.item-card {
display: flex;
flex-direction: column;
justify-items: end;
color: white;
width: 7em;
height: 7em;
text-align: center;
background-color: darkslategray;
margin: 5px 0;
img {
width: 40%; // TODO: how to scale?
height: 40%;
}
.text-container {
display: flex;
flex-direction: column;
.item-name {
display: inline-block;
font-size: 1.1em;
}
.description {
width: 99%;
font-size: 0.8em;
text-align: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
display: inline-block;
}
}
}
}
However the images do not scale down to keep the proportions with the others images, especially if narrow and long.
It all seems to look fine but it looks like your HTML code is missing the .text-container div and class.
<div class="item-card">
<div class="image">
<img src="../../../../assets/icons/apple.png" alt="Mela" />
</div>
<span class="item-name">Mela</span>
<span class="description">12</span>
</div>
should be
<div class="item-card">
<div class="image">
<img src="../../../../assets/icons/apple.png" alt="Mela" />
</div>
<div class="text-container">
<span class="item-name">Mela</span>
<span class="description">12</span>
</div>
</div>
Now for the text-overflow: ellipsis; this doesn't work on multi-lines unless you implement some JavaScript or something.
If there is any change to your code, I'd make the images a background-image instead. There could be other ways without this, but it's what I use to make sure the container is responsive with the image always responsive and centred.
For Example: https://codepen.io/StudioKonKon/pen/wRjOzr (Includes SCSS)
.image {
background-position: center center;
background-size: contain;
background-repeat: no-repeat;
font-size: 0;
}
.image-mela {
background-image: url("https://via.placeholder.com/150x175");
}
.image-latte {
background-image: url("https://via.placeholder.com/200x50");
}
.image-long {
background-image: url("https://via.placeholder.com/50x100");
}
.cards-container {
width: 100%;
margin: auto;
display: flex;
flex-wrap: wrap;
}
.cards-container .item-card {
display: flex;
flex-direction: column;
justify-items: end;
color: white;
width: 7em;
height: 7em;
text-align: center;
background-color: darkslategray;
margin: 5px;
padding: 0.5em;
box-sizing: border-box;
overflow: hidden;
}
.cards-container .item-card .image {
display: block;
margin: auto;
width: 40%;
height: 40%;
}
.cards-container .item-card .text-container {
display: flex;
flex-direction: column;
}
.cards-container .item-card .text-container .item-name {
display: inline-block;
font-size: 1.1em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.cards-container .item-card .text-container .description {
font-size: 0.8em;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
}
<div fxLayout="row" fxLayoutGap="5px" class="cards-container">
<div class="item-card">
<div class="image image-mela">Mela</div>
<div class="text-container">
<span class="item-name">Mela</span>
<span class="description">12</span>
</div>
</div>
<div class="item-card">
<div class="image image-latte">Latte</div>
<div class="text-container">
<span class="item-name">Latte</span>
<span class="description">1 description comes here, must be hidden if long text</span>
</div>
</div>
<div class="item-card">
<div class="image image-long">Long Image</div>
<div class="text-container">
<span class="item-name">Long Image Text</span>
<span class="description">must be hidden if long text</span>
</div>
</div>
</div>
Have you tried:
img {
width: 40%;
height: auto;
}
It should leave the image proportions consistent.
It is simple. I think it will solve the problem. :)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>item</title>
<style type="text/css" media="screen">
.item-single{
width: 100px;
background-color: #e7e7e7;
height: 100px;
text-align: center;
}
.item-single span{
display: block;
border: 1px solid #000; /* just to show the alignment */
}
.item-single img{
width: 50%; /* you can scale it down using width */
border:1px solid #000; /* just to show the alignment */
display: block;
margin: auto;
}
</style>
</head>
<body>
<div class="item-single">
<img src="http://sugamparajuli.com.np/wp-content/uploads/2019/01/banana.png">
<span class="item-name">Mela</span>
<span class="description">12</span>
</div>
</body>
</html>
This is the result.
item-image

How to position two block items on a single line

I'm trying aligned on one line sections new-setstion, user-section with inline-block but when I put text they diverge.
This is my css code, if you have better suggestions or criticisms please share them.
.page-content {
margin: 0 auto;
text-align: center;
}
div.news-section {
display: inline-block;
max-width: 500px;
min-width: 200px;
background-color: #fff;
word-wrap: break-word;
text-align: left;
}
div.user-section {
display: inline-block;
max-width: 300px;
min-width: 200px;
background-color: #fff;
word-wrap: break-word;
text-align: left;
}
This is my html code
<div class="page-content">
<div class="news-section">
<div class="news-section-header">
<h2>News</h2>
</div>
<!-- content -->
</div>
<div class="user-section">
<div class="user-section-header">
<h2>User section</h2>
</div>
<form class="user-login-form" method="POST">
<div><input type="email" name="user-name" placeholder="John-Doe#mail.com" /></div>
<div><input type="password" name="user-pass" placeholder="*****" /></div>
<div><input type="submit" name="sub-button" value="Login"/></div>
</form>
<!-- another div content -->
</div>
I think you want something like this: https://jsfiddle.net/oqvzraxs/, if I understood correctly your question.
I have added display: inline-flex to .page-content
.page-content {
display: inline-flex;
margin: 0 auto;
text-align: center;
}

div shifts to the bottom of the page with any content

I am attempting to put together a web page that has four areas: a header, footer, content, and controls. The header and footer should be fixed at the top and bottom of the page (respectively) and automatically size to their content. The controls should go on the far right side of the page (vertically between the header and footer) and is fixed-width. The content area should fill the remainder of the page.
I had this working, but now whenever I add any kind of content (even just a single-word paragraph element), the controls area moves to almost the very bottom of the page. You can see what I'm referring to here: http://jsfiddle.net/ym8vY/1/
If I leave the controls div completely empty, it lays out exactly how I want it: http://jsfiddle.net/ym8vY/
My body currently looks like:
<header>
<p>Header</p>
</header>
<div class="main">
<div id="streamGraph" class="page">
<div class="page-row">
<div class="page-content-container-outer">
<div class="page-content-container-inner">
<div id="graphContainer" class="page-content"></div>
</div>
</div>
<div class="page-controls-container-outer">
<div class="page-controls-container-inner">
<div class="page-controls"><!-- If anything goes inside here, it breaks -->
<div style="display: table; height: 100%;">
<div style="display: table-row; height: 0;">
<div>
<label for="sampleCount"># Samples:</label>
<input type="text" id="sampleCount" name="sampleCount" value="100" />
</div>
<div>
<label for="tagCount"># Tags:</label>
<input type="text" id="tagCount" name="tagCount" value="25" />
</div>
<div>
<label for="fromDate">From:</label>
<input type="date" id="fromDate" name="fromDate" />
</div>
<div>
<label for="toDate">To:</label>
<input type="date" id="toDate" name="toDate" />
</div>
<button id="tagsButton">Customize Tags</button>
<button id="refreshButton">Apply</button>
</div>
<div style="display: table-row;">
<div id="tagContainer" style="overflow: auto; height: 100%;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<p>Footer</p>
</footer>
And my CSS is:
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
display: table;
}
header, .main, footer {
display: table-row;
width: 100%;
}
header, footer {
background: lightgray;
}
.main {
height: 100%;
}
.page {
height: 100%;
display: table;
}
.page-row {
display: table-row;
width: 100%;
}
.page-content-container-outer {
display: table-cell;
width: 100%;
height: 100%;
padding: 10px;
}
.page-controls-container-outer {
display: table-cell;
height: 100%;
padding: 10px;
}
.page-content-container-inner {
border: solid;
border-color: gainsboro;
border-width: 5px;
border-radius: 10px;
width: 100%;
height: 100%;
padding: 5px;
}
.page-controls-container-inner {
border: solid;
border-color: gainsboro;
border-width: 5px;
border-radius: 10px;
height: 100%;
padding: 5px;
}
.page-controls {
height: 100%;
width: 300px;
}
.page-content {
height: 100%;
}
Your right-side div is being pushed down to the baseline. Add vertical-align:top to fix it:
div
{
vertical-align: top;
}
JSFiddle
Side note: The default value for vertical-align is baseline. Always keep this in mind when using cells and inline-blocks.
Add vertical-align:top; to your .page-controls-container-outer class
Change this
<div style="display: table-row; height: 0;">
to this
<div style="display: table-row; height: 0; float:left;">

Resources