CSS style div3 differently if div1 and div2 don't exist - html

If a user is signed up to my site, in their login area I have 3 divs as follows:
<div id="psts-cancel-link" class="psts-cancel-link"></div>
<div class="psts-receipt-link"></div>
<div id="psts-signup-another"></div>
These divs all have a width of 32% and sit inline with each other.
#psts-cancel-link {
background: white;
border-left: 3px solid #ccc;
padding: 1em;
width: 32%;
min-height: 270px;
float: left;
}
.psts-receipt-link {
background: white;
border-left: 3px solid #ccc;
min-height: 270px;
float: left;
width: 32%;
margin: 0 10px;
padding: 20px;
}
#psts-signup-another {
background: white;
padding: 1em;
border-left: 3px solid #ccc;
margin-bottom: 30px;
width: 32%;
min-height: 270px;
float: left;
}
When a user is not signed up, only one of the divs displays:
<div id="psts-signup-another"></div>
Is it possible to change the styling of this so that it's width is 100% when div1 and div2 aren't displayed?
So far I have tried this, but with no success:
#psts-cancel-link ~ .psts-receipt-link ~ #psts_existing_info #psts-signup-another {
width:100%;
}

Table Layout Implementation
Use a table layout. Specify display: table on the parent and display: table-cell on the child elements.
#psts-cancel-link {
background: tomato;
border-left: 3px solid #ccc;
padding: 1em;
min-height: 270px;
display: table-cell;
word-wrap: break-word;
}
.psts-receipt-link {
background: lightblue;
border-left: 3px solid #ccc;
min-height: 270px;
margin: 0 10px;
padding: 20px;
display: table-cell;
word-wrap: break-word;
}
#psts-signup-another {
background: tomato;
padding: 1em;
border-left: 3px solid #ccc;
margin-bottom: 30px;
min-height: 270px;
display: table-cell;
word-wrap: break-word;
}
.container {
display: table;
width: 100%;
table-layout: fixed;
}
Logged in
<div class="container">
<div id="psts-cancel-link"></div>
<div class="psts-receipt-link"></div>
<div id="psts-signup-another"></div>
</div>
Logged out
<div class="container">
<div id="psts-signup-another"></div>
</div>
Flexbox Layout Implementation
You can also use flexbox which expands and shrinks the child items according to the parent container.
#psts-cancel-link {
background: tomato;
border-left: 3px solid #ccc;
padding: 1em;
min-height: 270px;
flex: 1;
}
.psts-receipt-link {
background: lightblue;
border-left: 3px solid #ccc;
min-height: 270px;
margin: 0 10px;
padding: 20px;
flex: 1;
}
#psts-signup-another {
background: tomato;
padding: 1em;
border-left: 3px solid #ccc;
margin-bottom: 30px;
min-height: 270px;
flex: 1;
}
.container {
display: flex;
}
Logged in
<div class="container">
<div id="psts-cancel-link"></div>
<div class="psts-receipt-link"></div>
<div id="psts-signup-another"></div>
</div>
Logged out
<div class="container">
<div id="psts-signup-another"></div>
</div>

You could simply use :first-child if it's indeed the only child in the second case.
#psts-signup-another:first-child {}

You can use the adjacent selector. Have a look at the following snippet:
#psts-signup-another {padding: 5px; background: #f99;}
div + div + #psts-signup-another {padding: 5px; background: #99f;}
<h2>Div when three divs are present</h2>
<div class="theDivs">
<div id="psts-cancel-link" class="psts-cancel-link"></div>
<div class="psts-receipt-link"></div>
<div id="psts-signup-another"></div>
</div>
<h2>Div when three divs are not present</h2>
<div class="theDivs">
<div id="psts-signup-another"></div>
</div>

i think you should use another container div with a new class when user logout.
Logged:
<div class="container">
<div id="psts-cancel-link" class="psts-cancel-link"></div>
<div class="psts-receipt-link"></div>
<div id="psts-signup-another"></div>
</div>
Logout:
<div class="container logout">
<div id="psts-cancel-link" class="psts-cancel-link"></div>
<div class="psts-receipt-link"></div>
<div id="psts-signup-another"></div>
</div>
CSS:
.container.logout > div {
display:none;
}
.container.logout > .psts-signup-another {
display:block;
}

Related

Placing divs side by side and adding elements in it [duplicate]

This question already has answers here:
Align inline-block DIVs to top of container element
(5 answers)
Closed 2 years ago.
I wanted to have 3 divs side by side in a HTML document and I managed to achieve it where it looks something like this:
But whenever I tried adding objects such as text or any other objects, the div is always shifting down:
Could anyone help me out on this?
Edit
Thanks for the response but i forgot that i wanted a logo at the top left, then followed by the 3 divs below the logo, but adding "flex" property to the container leads to this:
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
background-color: #fff;
}
.container {
width: 100%;
height: 100%;
display: flex;
border: 1px solid black;
}
.input {
width: 450px;
height: 680px;
border-radius: 5px;
border: 3px solid black;
margin-top: 5px;
margin-left: 5px;
display: inline-block;
}
.output {
width: 650px;
height: 680px;
border-radius: 5px;
border: 3px solid black;
margin-left: 20px;
display: inline-block;
}
.output_2 {
width: 300px;
height: 680px;
border-radius: 5px;
border: 3px solid black;
margin-left: 20px;
display: inline-block;
}
<!--
this is the outermost shell
-->
<div class="container">
<!-- to add a logo at the top left -->
<div class = "sun_lg">
<img src = "images/sun.png" height = "50">
</div>
<div class="input">
<p>Hi</p>
</div>
<div class="output">
</div>
<div class="output_2">
</div>
</div>
Just add display:flex to your container.
To learn more about flexbox read the documentation.
You can also use grid
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
background-color: #fff;
}
.container {
width: 100%;
height: 100%;
border: 1px solid black;
display: flex;
flex-direction:column;
/* new */
}
.wrapper{
width: 100%;
height:auto;
display: flex;
}
.input {
width: 450px;
height: 680px;
border-radius: 5px;
border: 3px solid black;
margin-top: 5px;
margin-left: 5px;
}
.output {
width: 650px;
height: 680px;
border-radius: 5px;
border: 3px solid black;
margin-left: 20px;
display: inline-block;
}
.output_2 {
width: 300px;
height: 680px;
border-radius: 5px;
border: 3px solid black;
margin-left: 20px;
display: inline-block;
}
/* update for logo */
.sun_lg {
border: 1px solid #000;
flex: 1 1 100%;
}
<div class="container">
<!-- to add a logo at the top left -->
<div class="sun_lg">
<img src="https://via.placeholder.com/50x50" height="50">
</div>
<div class="wrapper">
<div class="input">
<p>Hi</p>
</div>
<div class="output">
</div>
<div class="output_2">
</div>
</div>
</div>
Define vertical-align to set the exact behavior of divs against texts baseline. I will use vertical-align:top in all child divs:
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
background-color: #fff;
}
.container {
width: 100%;
height: 100%;
border: 1px solid black;
}
.input {
width: 450px;
height: 680px;
border-radius: 5px;
border: 3px solid black;
margin-top: 5px;
margin-left: 5px;
display: inline-block;
vertical-align:top;
}
.output {
width: 650px;
height: 680px;
border-radius: 5px;
border: 3px solid black;
margin-left: 20px;
display: inline-block;
vertical-align:top;
}
.output_2 {
width: 300px;
height: 680px;
border-radius: 5px;
border: 3px solid black;
margin-left: 20px;
display: inline-block;
vertical-align:top;
}
<!--
this is the outermost shell
-->
<div class="container">
<div class="input">
<p>Hi</p>
</div>
<div class="output">
</div>
<div class="output_2">
</div>
</div>

CSS left and rghtDiv not aligning to left and right but top and bottom

My css and html looks like below. mRow is the main div and within that is my mRowLeft and mRowRight.
However instead of left and right I see them appear top left and bottom right.
div.mRow {
padding: 2px 25px 2px 0;
margin-top: 4px;
margin-bottom: 3px;
float: left;
text-align:left;
width: 350px;
/*border:1px solid green;*/
}
.mRowLeft {
padding: 2px 25px 2px 0;
margin-top: 4px;
margin-bottom: 3px;
float: left;
text-align:left;
width: 48%;
/*border:1px solid green;*/
}
.mRowRight {
padding: 2px 25px 2px 0;
margin-top: 4px;
margin-bottom: 3px;
float: right;
text-align:left;
width: 48%;
/*border:1px solid green;*/
}
///....
<div class="mRow">
<div class="mRowLeft"></div> --label
<div class="mRowLeft"></div> --10rows
<div class="mRowRight"></div> --label
<div class="mRowRight"></div> --10rows
</div>
...//
You should be putting your label and content under the same left/right div.
<div class="mRow">
<div class="mRowLeft">
<div>--label</div>
<div>10rows</div>
</div>
<div class="mRowRight">
<div>label</div>
<div>10rows</div>
</div>
</div>
Then you can either use inline-blocks:
.mRow {
white-space: nowrap;
width: 350px;
}
.mRowLeft,
.mRowRight {
display: inline-block;
white-space: normal;
width: 50%;
}
or use flexbox:
.mRow {
display: flex;
flex-direction: row;
width: 350px;
}
.mRowLeft,
.mRowRight {
width: 50%;
}
.mRow
{
display:flex;
justify-content:space-around;
}
<div class="mRow">
<div class="mRowLeft">
dfsf
<div class="mRowLeft">sdfvs</div>
</div>
<div class="mRowRight">
sdfs
<div class="mRowRight">sdfsd</div>
</div>
</div>

How to create a floating list of boxes with 1px border (using css)

If I stack a number of boxes (divs) together using float: left and set border: 1px solid black, there will be a 2px border between adjacent boxes. (Between boxes vertically, and also horizontally when boxes move to the next line.)
//html
<div class=boxes>
<div class="box">1</div>
<div class="box">1</div>
<div class="box">1</div>
<div class="box">1</div>
<div class="box">1</div>
<div class="box">1</div>
<div class="box">1</div>
<div class="box">1</div>
<div class=last></div>
</div>
//css
.boxes {
display: inline-block;
}
.last {
clear: both;
}
.box {
width: 200px;
height: 50px;
border: 1px solid gray;
line-height: 50px;
text-align: center;
float: left;
position: relative;
}
How can I achieve a similar layout with only a single pixel border between adjacent blocks?
I thought to add a "top left" border to the parent container, and then only set "right bottom" border for individual boxes. This partly works, but if the list of boxes flows over to the next line, then there will be a visible line on the top.
.boxes {
border-top: 1px solid gray;
border-left: 1px solid gray;
display: inline-block;
overflow: hidden;
}
.last {
clear: both;
}
.box {
width: 200px;
height: 50px;
border-bottom: 1px solid gray;
border-right: 1px solid gray;
line-height: 50px;
text-align: center;
float: left;
position: relative;
}
.boxes {
height: auto;
overflow: hidden;
padding: 1px 0 0 0;
border-left: 1px solid gray;
}
.box {
width: 200px;
height: 50px;
border: 1px solid gray;
border-left: 0;
line-height: 50px;
text-align: center;
float: left;
position: relative;
margin-top: -1px;
}
<div class="boxes">
<div class="box box1">1</div>
<div class="box box2">1</div>
<div class="box box3">1</div>
<div class="box box4">1</div>
<div class="box box1">1</div>
<div class="box box2">1</div>
<div class="box box3">1</div>
<div class="box box4">1</div>
</div>
Basically the outer container just set the left border and the inner boxes have a border on the other sides (not the left one). The trick is to shift all those blocks with a negative margin-top: -1px and place a padding-top: 1px on the parent container (so you can still see the top border of the first row).
I've also removed the empty element you inserted only for clearing purpose: height: auto and overflow: hidden on the parent container is enough (or look for the clearfix class which doesn't affect the overflow).
If you try to resize the viewport the borders are never overlapping.
You can use a trick with border-box and float the elements to be more responsive
.boxes {
float: left;
}
.box {
height: 50px;
width: 200px;
float: left;
box-shadow:
1px 0 0 0 gray,
0 1px 0 0 gray,
1px 1px 0 0 gray,
1px 0 0 0 gray inset,
0 1px 0 0 gray inset;
}
Example
All you need is:
.boxes {
margin-top: 1px;
margin-left: 1px;
}
.box {
width: 200px;
height: 50px;
border: 1px solid gray;
line-height: 50px;
text-align: center;
float: left;
margin-top: -1px;
margin-left: -1px;
}
<div class=boxes>
<div class="box box1">1</div>
<div class="box box2">1</div>
<div class="box box3">1</div>
<div class="box box4">1</div>
<div class="box box1">1</div>
<div class="box box2">1</div>
<div class="box box3">1</div>
<div class="box box4">1</div>
</div>
There is no need to add any other borders to anything but to .box directly and margin will do the magic
EDIT:
If you are making your design pixel-perfect then you should make your .boxes like:
.boxes {
margin-top: 1px;
margin-left: 1px;
margin-bottom: -1px;
margin-right: -1px;
}
and it will cancel out any effect created by margins
Here is how I'll do it, using a CSS variable, because it's cool:
(See comments in my code)
/* Added CSS variable, because it's nice to modify only here if needed */
:root{
--border: 1px solid gray;
}
.boxes {
display: inline-block;
width: auto;
margin: auto;
/* Added the below to make .last useless */
height: auto;
overflow: hidden;
/* Added for borders */
border-top: var(--border);
border-left: var(--border);
}
.box {
width: 200px;
display: inline-block;
height: 50px;
line-height: 50px;
text-align: center;
float: left;
position: relative;
/* Added for borders */
border-right: var(--border);
border-bottom: var(--border);
}
<div class=boxes>
<div class="box box1">1</div>
<div class="box box2">1</div>
<div class="box box3">1</div>
<div class="box box4">1</div>
<!-- <div class="last"></div> No need for that -->
</div>
Hope it helps.

Getting an equal 15px border with a grid layout

I'm trying to make a grid layout that's responsive with a 15px coloured border, it works ok but it when there's multiple grids, it doubles up the border i.e 30px where it joins.
https://jsfiddle.net/exm8xsgx/
html,
body {
height: 100%;
width: 100%;
}
.container {
height: 100%;
width: 100%;
}
.one {
height: 50vh;
width: 25%;
border-style: solid;
border-color: red;
border-width: 15px;
float: left;
}
<div class="container">
<div class="row">
<div class="one">one</div>
<div class="one">two</div>
<div class="one">three</div>
<div class="one">four</div>
</div>
</div>
This is another method I've tried. When browser width is restricted, the grids start to stack up and the border doubles up again, it should always be 15px whether they are next to each other or stacked.
https://jsfiddle.net/7bxtt82r/24/
html,
body {
height: 100%;
width: 100%;
}
.container {
height: 100%;
width: 100%;
}
.one:first-child {
height: 50vh;
width: 20%;
border-style: solid;
border-color: red;
border-left-width: 15px;
border-top-width: 15px;
border-bottom-width: 15px;
border-right-width: 15px;
float: left;
}
.one:not(:first-child) {
height: 50vh;
width: 20%;
border-style: solid;
border-color: red;
border-left-width: 15px;
border-top-width: 15px;
border-bottom-width: 15px;
border-right-width: 15px;
float: left;
margin-left: -15px;
}
<div class="container">
<div class="row">
<div class="one">one</div>
<div class="one">two</div>
<div class="one">three</div>
<div class="one">four</div>
</div>
</div>
I also don't know how many grids there will be so they will just continue to stack up.
You can use CSS table, and set border-spacing to 15px, example:
body {
margin: 0;
}
.row {
display: table;
table-layout: fixed;
border-collapse: separate;
border-spacing: 15px;
width: 100%;
background: red;
}
.one {
display: table-cell;
background: white;
}
<div class="row">
<div class="one">one</div>
<div class="one">two</div>
<div class="one">three</div>
<div class="one">four</div>
</div>
EDIT
If you need the items to wrap for different viewport width, you can use flexbox + box-shadow + media queries.
body {
margin: 0;
}
.row {
display: flex;
flex-wrap: wrap;
padding: 15px;
}
.one {
flex-basis: 25%;
box-shadow: 0 0 0 15px red;
background: white;
}
#media (max-width: 992px) {
.one {
flex-basis: 50%;
margin-bottom: 15px;
}
}
#media (max-width: 768px) {
.one {
flex-basis: 100%;
}
}
<div class="row">
<div class="one">one</div>
<div class="one">two</div>
<div class="one">three</div>
<div class="one">four</div>
</div>
Your external borders can stay on 15px but the border which touches another one has to be devided by 2 if you want a clean look with a same border around.
I used a default border of 10px and 20px for those not touching each other. (You can do the opposite: default 20px and 10px for those touching)
I dealt with this while building my simon game here
.squareCircled {
height: 250px;
width: 250px;
border: 10px solid gray;
}
.green {
background-color:#01B600; /*green*/
border-top-left-radius: 100%;
border-top:20px solid gray;
border-left:20px solid gray;
cursor: pointer;
}

How to align text to the right side of an img without using float:left so it wont change the default parent div height

How to I align text to the right side of the image icon like the one in the example picture.
I would usually use "float:left" but it's for a mobile responsive design so I prefer not using things like "float:left" because it ruins the red divs height with responsive designs.
I have to align the title, subsitle and a little square image.
It is easy to use float: left and NOT break the height of red border div.
You only have to add display: table-cell to the .app_top block. Here's the solution:
.app_top {
display: table-cell;
}
.app_top img {
float: left;
}
See the working example. Here's the code.
You could use display: inline-block instead.
#main-container {
border: 5px solid #3F3F3F;
width: 270px;
}
.container {
width: 250px;
height: 200px;
border: 5px solid #7F0008;
margin: 5px;
}
.box {
display: inline-block;
vertical-align: top;
width: 85px;
height: 85px;
background: #446C74;
margin: 5px;
}
.content {
display: inline-block;
vertical-align: top;
}
.title, .sub-title {
margin: 0;
padding: 3px 10px 3px 0;
}
.title {
font-size: 17px;
font-weight: bold;
}
.sub-title {
font-weight: bold;
color: #3F3F3F;
}
.img {
background: url(http://placehold.it/100/25);
width: 100px;
height: 25px;
border: 5px solid #EBEAAE;
}
<div id="main-container">
<div class="container">
<div class="box">
</div>
<div class="content">
<p class="title">Title</p>
<p class="sub-title">Sub-Title</p>
<div class="img"></div>
</div>
</div>
<div class="container">
<div class="box">
</div>
<div class="content">
<p class="title">Title</p>
<p class="sub-title">Sub-Title</p>
<div class="img"></div>
</div>
</div>
</div>
Maybe another option is to put the attribute in a parent div instead of the element
html:
<div id="wrapper">
<div class="twoColumn">
<img src="https://pbs.twimg.com/profile_images/444650714287972352/OXTvMFPl.png" />
</div>
<div class="twoColumn">
<p> this is a testingalot test</p>
<button> mybutton </button>
</div>
</div
css:
#wrapper{
border: 1px solid black;
}
.twoColumn{
width: 49%;
float:left;
border: 1px solid red;
}
button{
width: 50px;
height: 40px;
background: red;
}
img{
max-width: 100%;
}
http://jsfiddle.net/Equero/df2wvcet/
I hope it's help
Most simple solution would be to change your markup structure by wrapping your spans in a div just the way you did with the image, then add .app_top div{display:inline-block} .app_top div span{display:block}
.top{
width: 95%;
position: fixed;
background-color: #f7f7f7;
padding-top: 10px;
padding-bottom: 10px;
padding-left: 3%;
padding-right: 3%;
border-bottom: 1px solid #b2b2b2;
}
.search{
width: 100%;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: none;
background-color: #e3e3e6;
}
.search::-moz-focus-inner {
border: 0;
padding: 0;
}
.items{
background-color: #ffffff;
width: 100%;
padding-top: 50px;
}
.app{
margin-left: 25px;
margin-right: 25px;
}
.app_top div{display:inline-block}
.app_top div span{display:block}
<div class="main">
<div class="top" >
<input type="text" class="search" />
</div>
<!-- Items -->
<div class="items" style="border: 1px solid black; padding-top: ">
<div class="app" style="border: 1px solid red;" >
<div class="app_top">
<div>
<img src="_img1.jpg" width="95"/>
</div>
<div>
<span class="app_txt" style="border: 1px solid aqua;"> text text - House text house! Las...</span>
<span class="ltd" style="border: 1px solid pink;"> textic-texttive ltd</span>
<span class="" style="border: 1px solid blue;"> </span>
</div>
</div>
<div class="app_bottom">
</div>
</div>
</div>
.content contains all text in right side. If you use overflow:hidden the height of div will stay normal.
img { float:left; }
.content { overflow:hidden; }