I have 2 divs, one nested inside of the other. According to the page design, the nested div needs to appear normally inside its parent on a large screen, as in this image.
But on a small screen, the nested div needs to appear to be above the parent div, as in this image.
I don't want to position the child element absolutely, because it's a very poor and inflexible choice, especially for a responsive page.
HTML for divs / CSS for divs (on a large screen only):
.container-div {
background-size: 100% auto;
margin-bottom: 20px;
-webkit-box-shadow: 0px 1px 3px 0px rgba(0,0,0,.73), 0px 0px 18px 0px rgba(0,0,0,.13);
-moz-box-shadow: 0px 1px 3px 0px rgba(0,0,0,.73), 0px 0px 18px 0px rgba(0,0,0,.13);
box-shadow: 0px 1px 3px 0px rgba(0,0,0,.73), 0px 0px 18px 0px rgba(0,0,0,.13);
}
.child-div {
position: absolute;
border: 3px solid white;
width: 400px;
height: 200px;
margin-bottom: 10px;
margin-right: 10px;
bottom: 0;
}
<div class="container-div">
<div class="child-div">
...
</div>
</div>
Use an inner-parent and flexbox.
.parent {
display: flex;
flex-flow: column-reverse;
}
.inner-parent {
background: red;
}
.child {
background: blue;
}
#media screen and (min-width: 640px) {
.parent {
flex-flow: column;
background: red;
}
}
/* Reset and basic styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.parent {
align-items: center;
width: 200px;
}
.inner-parent {
height: 50px;
width: 100%;
padding: 20px;
text-align: center;
}
.child {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
height: 50px;
width: 75%;
}
<div class="parent">
<div class="inner-parent">PARENT</div>
<div class="child">CHILD</div>
</div>
When smaller than 640px use .inner-parent as the lower div and use the real parent when larger than 640px by making it's background color match. To fix the order just switch from column-reverse to column or just use order to change the order of just one of the child divs.
Related
I'm putting a label and an input inside a div that is a flex container and flex-direction is set to column. The container naturally takes the width of the input and not the label. I'm trying to figure out why that is and if there is a way I can get the container to take the width of the label (or what the width of the label should be)
"Relationship to Patient" is the label/input in question.
What I want (on my my extra large screen):
What I'm getting (on my large screen):
HTML (using React and Nextjs):
<div className={styles.inputContainer}>
<label className={styles.label}>Relation to Patient</label>
<select className="form-field">
<option>Self</option>
<option>Child</option>
<option>Spouse</option>
<option>Parent</option>
<option>Other</option>
</select>
</div>
CSS:
:root {
--primary: #50657a;
--secondary: #7a5050;
--tertiary: #797a50;
--lightGray: #bababa;
--darkGray: #4d4d4d;
--extraLightGray: #ededed;
}
.inputContainer {
display: flex;
flex-direction: column;
justify-content: flex-end;
/* width: 200px */
height: 60px;
margin: 0 .5rem;
}
.label {
color: var(--secondary);
}
.formRow {
width: 100%;
display: flex;
margin: .5rem 0;
/* justify-content: space-around; */
}
.form-field {
border: 1px solid #bababa;
line-height: 1.5rem;
height: 2rem;
padding: 5px;
border-radius: 5px;
}
.form-field:focus {
outline: 0px;
-webkit-box-shadow: 0px 0px 3px 3px rgba(80,101,122,.5);
-moz-box-shadow: 0px 0px 3px 3px rgba(80,101,122,.5);
box-shadow: 0px 0px 3px 3px rgba(80,101,122,.25);
}
Parent element:
<div className={styles.formRow} style={{ marginTop: '0' }}>
/* A bunch of other code */
<div className={styles.inputContainer}>
<label className={styles.label}>Relation to Patient</label>
<select className="form-field">
<option>Self</option>
<option>Child</option>
<option>Spouse</option>
<option>Parent</option>
<option>Other</option>
</select>
</div>
</div>
So, reminder, I'm trying to figure out why the flex container chooses the width of the input and not the label and also how I can get the desired results.
I very much appreciate any/all help and answers!!
I Set display:Flex to the .container element. I had put two children on the element. and gave max-width to the child(.box) of second flex-Item. But it does not seems to work.
body {
font-family: sans-serif
}
.container {
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -moz-flex;
display: flex;
}
.par {
position: relative;
margin-left: 7px
}
.round {
height: 17px;
width: 17px;
background: #cacaca;
border-radius: 50%
}
.box {
padding: 10px 16px;
box-shadow: 0 3px 15px 0px rgba(0, 0, 0, 0.2);
background: #fff;
position: absolute;
font-size: 14px;
color: #333;
max-width: 200px;
left: -11px;
top: 28px;
}
.box::after {
content: "";
position: absolute;
height: 10px;
width: 10px;
background: #fff;
box-shadow: 2px 2px 5px -1px rgba(0, 0, 0, 0.17);
transform: rotate(-137deg);
top: -5px;
left: 16px;
}
<div class="container">
<div>Title</div>
<div class="par">
<div class="round"></div>
<div class="box">This is a Paragraph Text</div>
</div>
</div>
Js Fiddle Link
The position: absolute child's width depends on it's position: relative parent.
In your case, .box's width depends on .par while .par is too narrow to contain the word "Paragraph". That's why the .box's width is depending to the its longest word in the content.
I don't think you can set dynamic width to .box while not exceeding 200px and also keep the current width of .par. There maybe 2 ways to solve your problem.
set .par's to width: 200px
set fixed width: 200px to .box
You need remove position: relative for .par and remove left and top for .box instead add styles for .box like margin: 8px 0 0 -11px;, than max-width will be work correct.
Is there any better way of setting two borders like in the example below? I could only do it with positioning. I'm new here so I apologize for any mistakes whatsoever.
.border1 {
margin: 0 auto;
height: 300px;
width: 250px;
border: 9px solid red;
position: relative;
}
.border2 {
border: 9px solid blue;
height: 250px;
width: 300px;
position: absolute;
top: 12px;
left: -33px;
}
<div class="border1">
<div class="border2"></div>
</div>
Absolute is indeed a good and easy way here.
You can also use a pseudo and only coordonates to size the second border box.
.border1 {
margin: 0 auto;
min-height: 150px;/* allow it to grow */
width: 250px;
padding:20px 0.5em;
border: 9px solid red;
position: relative;
}
.border2:before {
content:'';
border: 9px solid blue;
pointer-events:none;/* to allow clicking through else you may use a negative z-index */
position: absolute;
top: 12px;
bottom:12px;
left: -33px;
right:-33px;
}
<div class="border1 border2">
add anything here instead setting height
</div>
This is a different approach. I used box-shadow as the second border and you will no longer need a second div for second border.
.border{
margin:0 auto;
height:300px;
width:250px;
border:9px solid red;
position:relative;
box-shadow: 0 0 0px 9px blue;
}
<div class="border"></div>
You can do it with the Flexbox and without unnecessary calculations:
.border1 {
margin: 0 auto;
height: 300px;
width: 250px;
border: 9px solid red;
display: flex; /* displays flex-items (children) inline */
justify-content: center; /* centers them horizontally */
align-items: center; /* and vertically */
}
.border2 {
flex: 0 0 300px; /* doesn't shrink, flex-basis set to "300px" (initial width) */
border: 9px solid blue;
height: 250px;
}
<div class="border1">
<div class="border2"></div>
</div>
Normally the elements of an HTML markup appear in the order they are written in the markup file, and the inline elements appear from left to right.
But I want the children of a certain div (only, NOT all the elements of the entire page) to appear from right to left.
In case you wonder why it is needed, I want to do this to solve the following problem:
PROBLEM:
JSFiddle here.
.wrapper {
height: 100%;
width: 826px;
margin: 50px auto;
display: table;
background-color: #003b80;
}
.cell {
display: table-cell;
vertical-align: top;
}
.left-cell {
width: 50%;
background-color: chocolate;
}
.right-cell {
background-color: darkslategrey
}
.step-container {
max-height: 200px;
font-size: 0;
}
.right-cell .step-container {
margin-top: 125px;
}
.content-box {
display: inline-block;
width: 350px;
height: 200px;
/*border: 5px solid blue;*/
font-size: 0;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.69);
-moz-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.69);
-webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.69);
background-color: dodgerblue
}
.right-cell .content-box {
background-color: darkturquoise
}
.middle-cell {
height: 100%;
background-color: white;
width: 1.5px;
font-size: 0;
box-shadow: 0px 0px 10px black;
-moz-box-shadow: 0px 0px 10px black;
-webkit-box-shadow: 0px 0px 10px black;
}
.number-outer-container {
display: inline-block;
position: absolute;
}
.left-cell .number-outer-container {
/*margin-left:39px;*/
}
.number-inner-container {
height: 200px;
display: flex;
flex-direction: column;
justify-content: center;
}
.number-banner {
width: 50px;
height: 50px;
background-color: crimson;
-moz-border-radius: 25px;
-webkit-border-radius: 25px;
border-radius: 25px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
-webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
}
.notch-outer-container {
display: inline-block;
}
.left-cell .notch-outer-container {
margin-right: 24px;
}
.right-cell .notch-outer-container {
margin-left: 10px;
}
.notch-inner-container {
height: 200px;
display: flex;
flex-direction: column;
justify-content: center;
}
.notch {
width: 0;
height: 0;
border-top: 15px solid transparent;
border-bottom: 15px solid transparent;
}
.left-face-notch {
border-right: 15px solid #520f23;
}
.right-face-notch {
border-left: 15px solid #571780;
}
<div class="wrapper">
<div class="cell left-cell" align="left">
<div class="step-container">
<div class="content-box"></div>
<div class="notch-outer-container">
<div class="notch-inner-container">
<div class="right-face-notch notch"></div>
</div>
</div>
<div class="number-outer-container">
<div class="number-inner-container">
<div class="number-banner"></div>
</div>
</div>
</div>
</div>
<div class="cell middle-cell"></div>
<div class="cell right-cell" align="right">
<div class="step-container">
<div class="number-outer-container">
<div class="number-inner-container">
<div class="number-banner"></div>
</div>
</div>
<div class="notch-outer-container">
<div class="notch-inner-container">
<div class="left-face-notch notch"></div>
</div>
</div>
<div class="content-box"></div>
</div>
</div>
</div>
In this SSCCE, inside .left-cell .step-container, I have three elements appearing on the same line: .content-box, .notch-outer-container, and .number-outer-container; and to make the .notch appear to be overlapping the right-cell by 50% of its width, I gave .number-outer-container a position:absolute; and .notch-outer-container a margin-right which pushes the number-outer-container to right side to an extent that it appears to be overlapping the (.middle-cell and) right-cell by 50% of it's width.
The problem is that in the .right-cell, this strategy is NOT working. First the .number-right-container appears and still it is absolute, I can not give it a left property with value relative to its parent (otherwise I would try a left:-25px to make it appear 25px behind the left edge of its parent, because it has width:50px;). Then the .notch is hidden below it...
So I am thinking about finding a way through which I can get the elements render from RTL (Right To Left) rather than LTR only inside .right-cell on the page. So that I can follow the same strategy I have used for the .left-cell, in the .right-cell.
There's numerous ways to achieve what you want using either flexing, floats or other options, but I'd say one of the easiest ways, if the rest of the layout works as you want it to, is to use the direction attribute.
div {
direction: rtl;
}
div div {
display: inline-block;
direction: ltr;
}
<div>
<div>first</div>
<div>second</div>
<div>last</div>
</div>
I am trying to get an image to float to the right of my div with a little space around the edges. I want the image to fill the majority of the div but with space for the link 'view project' beneath it. I've tried different floats, widths and even adjusted padding but still cannot get it to work. Can anyone tell me how to rectify this? Many thanks in advance. This is the page link if needed: http://me14ch.leedsnewmedia.net/portfolio/design.html
HTML:
<div id="middle">
<div class="section group">
<div class="block-1">
<h2>Logo Redesign & Style Guide</h2>
<p><h3>This brief involved...</h3></p>
<div class="snapshot">
<img src="portfolioresources/scenelogo.png">
View Project
</div></div>
<div class="block-2">
<h2>TV Idents</h2>
<p>This brief involved...</p>
View Project
</div>
</div>
<div class="section group">
<div class="block-3">
<h2>Web Banners</h2>
<p>This brief involved...</p>
View Project
</div>
<div class="block-4">
<h2>Multiformat Campaign</h2>
<p>This brief involved...</p>
View TV Idents
</div>
</div>
</div>
And the CSS for this particular bit (although inspect element might show other things that are affecting my divs):
/* design page grids */
.section {
clear: both;
padding: 0px;
margin: 0px;
}
/* COLUMN SETUP */
.colu {
display: block;
float:left;
margin: 1% 0 1% 1.6%;
}
.colu:first-child { margin-left: 0; }
/* GROUPING */
.group:before,
.group:after { content:""; display:table; }
.group:after { clear:both;}
.group { zoom:1; /* For IE 6/7 */ }
/* GRID OF TWO */
.span_2_of_2 {
width: 100%;
}
.span_1_of_2 {
width: 49.2%;
}
/* GO FULL WIDTH AT LESS THAN 480 PIXELS */
#media only screen and (max-width: 480px) {
.colu {
margin: 1% 0 1% 0%;
}
}
#media only screen and (max-width: 480px) {
.span_2_of_2, .span_1_of_2 { width: 100%; }
}
/* style grids */
#middle {
width: 90%;
margin: 0px auto;
padding: 10px;
}
.block-1 {
background-color:#ECECEC;
width: 80%;
margin: 0px auto;
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
height: 200px;
padding: 10px;
}
.block-2 {
background-color: white;
width: 80%;
margin: 0px auto;
margin-top: 20px;
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
border-top: 2px solid #FADBC8;
border-bottom: 2px solid #FADBC8;
height: 200px;
padding: 10px;
}
.block-3 {
background-color:#ECECEC;
width: 80%;
margin: 0px auto;
margin-top: 20px;
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
height: 200px;
padding: 10px
}
.block-4 {
background-color: white;
width: 80%;
margin: 0px auto;
margin-top: 20px;
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
border-top: 2px solid #FADBC8;
border-bottom: 2px solid #FADBC8;
height: 200px;
padding: 10px;
}
.block-1 img {
height: 140px;
float: right;
clear: both;
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
}
.snapshot a {
float: right;
text-decoration:underline;
font-family: "Raleway";
}
DO this in snapshot class
<div class="snapshot">
<div class="wrap" ><img src="portfolioresources/scenelogo.png"></div>
View Project
</div></div>
and add this to ur css file to sortify your error
.wrap{
padding:2px;
}
While doing these kinda things on your own is definitely useful, so you can learn the ropes and inner workings first, be sure to use a css framework in the future (like bootstrap) so you can knock these out quickly.
<div class="view-project">
<img ... />
<span>View Project</span>
</div>
In your css:
.view-project{ float: right; width:300px; padding:40px; }
.view-project img,.view-project span{ display:block; }
A suggestion: if you want your image at the right of the div with view project beneath, I think you should contain them in another div. Like this:
<div class="snapshot">
<div>
<img src="portfolioresources/scenelogo.png">
View Project
</div>
</div>
Then float that div right and remove all other floats.
If you want the image on top of view project, set display: block; to your 'a' elements.
You need to at least define a width for snapshot. by making the width of snapshot equal the width of the image, this will leave no room for the link and will force it to drop below the image. Remove any floating on the image and link, and rather float snapshot to the right