padding-right not applying to last child - javascript

Trying to make an image timeline interface, and I'm a little stuck. The marker is always at the center so the first element has padding-left: 50% which is working fine. However, I also want the last element to have padding-right: 50% so I can scroll all the way to the end of the last element.
Here's the jsfiddle: https://jsfiddle.net/da3hk2xz/
As you can see #timeline:last-child is not being applied.
var timeline = document.getElementById("timeline");
for (var i = 0; i < 25; i++) {
var img = document.createElement("img");
img.src = "http://placehold.it/300x150?text=" + i
timeline.append(img)
}
html,
body {
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
}
#timeline {
width: 100%;
height: 150px;
background-color: red;
overflow-x: scroll;
display: flex;
flex-wrap: nowrap;
position: absolute;
bottom: 0;
box-sizing: border-box;
}
#timeline:nth-child(1) {
padding-left: 50%;
}
#timeline:last-child {
padding-right: 50%;
}
#marker {
/* http://apps.eky.hk/css-triangle-generator/ */
width: 0;
height: 0;
border-style: solid;
border-width: 35px 17.5px 0 17.5px;
border-color: #007bff transparent transparent transparent;
position: absolute;
bottom: 115px;
/* 150 - 35 */
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
}
#line {
width: 2px;
height: 115px;
/* 150 - 35 */
background-color: purple;
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
}
<div id="timeline"></div>
<div id="marker-container">
<div id="marker"></div>
<div id="line"></div>
</div>

Simply changing the selectors in question from what you have to this below should work:
#timeline :nth-child(1) {
padding-left: 50%;
}
#timeline :last-child {
padding-right: 50%;
}
The reason for this is that the last "phrase" in the selector is the element to which the styles will be applied. In your fiddle, the last "phrase" was the #timeline element itself, thus it was receiving the padding. Putting a space between #timeline and :last-child made the :last-child phrase the last one, and since the space in the selector means "any decendant", the decendant will receive the padding.
In plain english:
#timeline:last-child: The last child, of a parent element, that also has an id of timeline.
#timeline :last-child: The last element that is a child of the element with an id of timeline.
Targeting the direct decendant would work as a safer and more efficient solution as well:
#timeline > :nth-child(1)
#timeline > :last-child
CSS is fun.

Tested this and it worked out
#timeline img:nth-child(1) {
padding-left: 50%;
}
#timeline img:last-child {
padding-right: 50%;
}

Here's a cool solution you might like:
Instead of padding, use pseudo flex items.
#timeline::before {
content: "";
flex: 0 0 50%;
background-color: red;
}
#timeline::after {
content: "";
flex: 0 0 50%;
background-color: red;
}
jsFiddle

There you go:
https://jsfiddle.net/da3hk2xz/1/
Your layout uses a bit much absolute positioning, so I had to change it around a bit. The main thing was that I added #right-padding and #timeImgContainer.

Related

How to make an image the full width of a screen with dictating the height

I created an image slider, but I am running into an issue. I want the width of the images to be the entire width of the screen; I accomplished this. However, my images' height are more than 100% of the height of the screen. I am wanting the height to be around 50-70% of the screen (preferably 50%). I tried adding height: 70vh; to my images, but that did not help.
Can anyone suggest something to help this?
My slider can be viewed at: http://realtorcatch.com/slider3
My code is:
* {
padding: 0;
margin: 0;
}
body {
font-family: Sans-Serif;
}
img {
max-width: 100%;
/*height: 70vh;*/
}
.cycle-slideshow {
width: 100%;
display: block;
position: relative;
margin: 0 auto;
}
.cycle-prev, .cycle-next {
font-size: 200%;
color: #FFF;
display: block;
position: absolute;
top: 50%;
margin-top: -10px;
z-index: 999;
cursor: pointer;
}
.cycle-prev {
left: 10%;
}
.cycle-next {
right: 10%;
}
.cycle-pager {
width: 100%;
text-align: center;
display: block;
position: absolute;
bottom: 20px;
z-index: 999;
cursor: pointer;
}
.cycle-pager span {
text-indent: 100%;
white-space: nowrap;
width: 12px;
height: 12px;
display: inline-block;
border: 1px solid #FFF;
border-radius: 50%;
margin: 0 10px;
overflow: hidden;
}
.cycle-pager .cycle-pager-active {
background-color: #FFF;
}
<div class="cycle-slideshow">
<span class="cycle-prev">〈</span>
<span class="cycle-next">〉</span>
<span class="cycle-pager"></span>
<img src="images/subway.jpg" alt="subway">
<img src="images/beach.jpg" alt="beach">
<img src="images/space.jpg" alt="space">
</div>
On your img declaration, instead of max-width set width to 100% and height to 70vh. If you'd like more variety in the height, try setting the min-height to be 50vh and the max-height to be 70vh.
Be warned, this will skew your images and make them look disproportionate.
Alternate solution:
Create a "scrim". By this, I mean create a box that covers up the bottom half of the page. You can actually do this with a pseudo-element from your wrapper:
.cycle-slideshow {
position: relative;
...
}
.cycle-slideshow:after {
content: '';
width: 100%;
height: 50%; //50% of parent element
background-color: white;
position: absolute;
top: 50%;
left: 0;
z-index: 2;
}
change style of img to img {width: 100%; height: 100vh;}
It will work for you. Thank you.
try this,, Hope it will help you.
var vHeight = $(window).height()/2, // for 50%
vWidth = $(window).width(),

Smart Sticky Navigation Menu

I'm having a small problem with some text jumping around in my sticky menu. This is my code: http://jsfiddle.net/u6ywraj8/
As you can see, I want the red #menu to stick to the top when a user scrolls down. However, the text in the top left part of the menu jumps around. I want this text to always be in the top left part of the red menu, I don't want it to have the initial ~100px padding.
Thank you for your help!
Try this one
sticknav {
background: none repeat scroll 0 0 #ffffff;
display: inline-block;
height: 30px;
left: 0;
margin-left: 0;
margin-right: 0;
position: relative;
right: 0;
width: 100%;
z-index: 9999;
}
Add float: left; to this class sticknav{}
sticknav {
background: #ffffff;
height: 30px;
width: 100%;
margin-right: 0px;
margin-left: 0px;
left: 0px;
right: 0px;
position: relative;
z-index: 9999;
float: left;
}

Can I make this javascript sidebar in CSS (including the animation)?

I found this when searching on how to make a sidebar and thought it was good, but it's in JavaScript and I don't want to use JavaScript. So am I able to do this using only CSS and HTML/5?
$('button').toggle(
function() {
$('#B').animate({left: 0})
}, function() {
$('#B').animate({left:200})
})
Here's a snippet of the above example:
$('button').toggle(
function() {
$('#B').animate({left: 0})
}, function() {
$('#B').animate({left:200})
})
html, body {
margin: 0;
padding: 0;
border: 0;
}
#A, #B {
position: absolute;
}
#A {
top: 0px;
width: 200px;
bottom: 0px;
background:orange;
}
#B {
top: 0px;
left: 200px;
right: 0;
bottom: 0px;
background:green;
}
#BB {
top: 0px;
left: 0px;
right: 0;
bottom: 0px;
background:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<div id="A"></div>
<div id="B"><button>toggle</button></div>
There's also a way to make this type of navigation feasible by performing a workaround that uses the :checked property of the checkbox input and the General Sibling CSS Selector ~ in order to choose the #A and #B divs and resize them to suit your needs when the checkbox is toggled.
In my example I emulated a toggle button by hiding the actual checkbox and styling the label for the checkbox (the label is also clickable and will trigger the checked attribute in the input element).
The shortcomings in this approach is that in order for the sibling selector to work, you have to actually have the toggle element in the same level as the other elements, which required some extra positioning work.
html,
body {
margin: 0;
padding: 0;
border: 0;
}
a {
display: inline-block;
padding: 1em;
text-decoration: none;
color: #fff;
background: rgba(0, 0, 0, 0.5);
border-radius: 0 5px 5px 0;
}
#A,
#B {
position: absolute;
transition: all 500ms;
}
#A {
top: 0px;
width: 200px;
bottom: 0px;
background: orange;
}
#B {
top: 0px;
left: 200px;
right: 0;
bottom: 0px;
background: green;
}
/*Hide the checkbox*/
#toggle {
display: none;
}
label {
position: relative;
/*Set the left position to the same as the sidebar */
left: 200px;
top: 10px;
margin: 5px;
z-index: 2;
transition: all 500ms;
background: #FFF;
padding: 4px 6px;
background: orange;
}
/* Initial sidebar state */
#toggle ~ #A {
left: 0;
}
/*move both containers on toggle*/
#toggle:checked ~ #A,
#toggle:checked ~ #B {
left: -200px;
}
/*move label to follow sidebar animation*/
#toggle:checked,
#toggle:checked ~ label {
left: 0;
background: #FFF;
}
<div id="A"></div>
<input id="toggle" type="checkbox">
<label for="toggle">Toggle</label>
<div id="B"></div>

center vertical line between divs

I have a div named welcome-inputs and within other two left and right
The div named left needs to be on the left side welcome-inputs and the div named right right side of welcome-inputs.
left and right have width = 100px
Need for a line that is at the MIDDLE of the two, signaling the separation.
view the code: http://jsfiddle.net/gn1asdmh/3/
The red line must be in the middle of the images (the images represent left and right)
jsFiddle demo
Add a span element between .left and .right
<span class="middleLine"></span>
CSS:
.welcome-inputs {
float: none;
margin: 0 auto;
width: 80%;
background:white;
height:100px;
text-align:center; /* ADD THIS */
}
.welcomeforms {
color: #6B6B6B;
margin: 0 auto;
width: 100px !important;
}
.left {
float: left;
/*border-right: 3px solid red; REMOVE THIS */
}
.right {
float: right;
}
body {
background:blue;
}
span.middleLine{
display:inline-block;
border-right: 2px solid red;
margin-left:-1px; /* cause the border is 2px */
height:100%;
}
JSFiddle
The other way to resolve it.
.left {
position:absolute;
top: 0;
left: 0;
}
.right {
position:absolute;
top: 0;
right: 0;
}
If you add position: relative to .welcome-inputs, you can use an ::after or ::before pseudo-element on .left or .right like this:
.left::after {
border-right: 3px solid red;
content: "";
height: 100px;
position: absolute;
top: 0;
left: calc((100% - 3px) / 2); // or use '50%' for better compatibility, but less exactness
}
and get rid of the border-right on .left
JSFiddle Here
Just use generated content on the parent element. There is no reason in the given example to use structural markup for this.
Updated fiddle, http://jsfiddle.net/gn1asdmh/26/
.welcome-inputs {
float: none;
margin: 0 auto;
width: 80%;
background:white;
height:100px;
position: relative;
}
.welcome-inputs::before {
content: '';
display: block;
position: absolute;
outline: 1px solid red;
left: 50%;
width: 0;
height: 100px;
}
.welcomeforms {
color: #6B6B6B;
margin: 0 auto;
width: 100px !important;
}
.left {
float: left;
}
.right {
float: right;
}
body {
background:blue;
}
The cleanest way to do it would be to use an HTML table. This will keep it responsive. Try something like the below code.
.welcome-inputs {
width: 100%;
}
#leftInput,
#rightInput {
width: 100px;
}
#separatorInput {
text-align: center;
}
#dividingLine {
display: inline-block;
height: 100%;
width: 5px;
background: red;
}
<table class="welcome-inputs">
<tr>
<td id="leftInput">
<img width="100%" src="http://news.bbcimg.co.uk/media/images/71832000/jpg/_71832498_71825880.jpg" />
</td>
<td id="separatorInput"><div id="dividingLine"</td>
<td id="rightInput">
<img width="100%" src="http://news.bbcimg.co.uk/media/images/71832000/jpg/_71832498_71825880.jpg" />
</td>
</tr>
</table>
Even better: no need to use any empty/dummy elements. We rely on using pseudo-elements instead. In this case I will use ::before:
.welcome-inputs {
float: none;
margin: 0 auto;
width: 80%;
background:white;
height:100px;
position: relative; /* new property added to original one */
}
.welcome-inputs::before {
content: '';
position: absolute;
top: 0;
bottom: 0;
width: 3px;
background-color: red;
left: 50%;
transform: translateX(-50%);
}
Just remember to declare position: relative on the parent element. See fiddle here: http://jsfiddle.net/teddyrised/gn1asdmh/28/
p/s: You might want to use vendor prefixes for transform, to maximise cross-browser compatibility.
to add some idea to these answers , you may think as well of :box-sizing, calc() for instance , or even a simple background image/repeat/sizing

WebKit height differences

Picture
CSS
#sub-nav {
position: absolute;
top: 207px;
left: 16px;
width: 192px;
z-index: 4;
background: url('../img/transparent.png');
overflow: hidden;
}
#logo-buttons-bg {
position: relative;
padding: 0 0 60px 0;
width: 208px;
//background-gradient
z-index: 8;
}
#logo-buttons-bg ul {
padding: 8px 21px;
list-style-type: none;
}
jQuery:
var containerHeight = $("#logo-buttons-bg ul").height();
$("#sub-nav").height(containerHeight - 25);
How can I fix it ? I've tried to add different elements for var containerHeight, changed 25 to another CSS element with specific height… the result is exactly the same.
Normalize.css fixed the problem, Thanks to Vucko
I had a similar issue with FF and Chrome. I was using .height and switched to .outerHeight(true)
http://princepthomas.blogspot.com/2011/07/jquery-height-vs-outerheight.html

Categories

Resources