i have a sticky nav that when it sticks (position: fixed being applied) the width is changing to push the right of the navbar off the screen.
a screen recording example
a codesandbox eample
Using react/hooks and styled components. a hook is applying the prop of sticky: true (see code below).
I have tried a few different combinations of setting width: 100% or width: 100vw in both the non-sticky and sticky styles.
in the video you can see 2 things happening when the nav becomes "sticky". the border-radius-bottom-right is disappearing and the content of the nav is being pushed to the right. When not sticky, the nav has a width of 808px, when sticky it grows to 840px. To be clear I'm not saying the border radius style is being removed, but the border right is now off screen.
the code for the nav:
const Wrapper = styled.div`
padding: 1rem;
display: flex;
justify-content: center;
font-size: 1.5rem;
background-color: white;
color: black;
/* width: auto; */
/* width: 100%; */
z-index: 1;
margin: 0;
box-shadow: 0px 2px 10px #273136;
height: 30px;
border-radius: 0 0 10px 10px;
${props => props.sticky && css`
position: fixed;
top: 0;
width: 100vw;
`}
`;
This is being rendered inside of another wrapper component, wrapping the entire app, with the following styles:
text-align: center;
font-size: 10px;
color: black;
display: flex;
flex-direction: column;
max-width: 100vw;
You set widht:100vw to the fixed element which makes wider than the body because vw doesn't care about the scrollbar it will be difficult to work with, i suggest you use width:100%
Also because you have box-sizing set to content-box the padding and border won't be considered as content so they will influence the width, and let's not forget about the default margin:8px on the body
to accommodate for all this we can use calc()
instead of 100vw you should use 100% because 100% gives us the exact width of the parent excluding the width of the scrollbar.
Solution
After you set position:fixed
You also add
left:8px; // to push it 8px from the left because of the default margins on the body
width:calc(100% - 48px);
Why 48x ?
left padding (16p) + right padding(16px) + left body margin(8px) + right body margin(8px) = 48px
Why left body margin ? didn't we use left:8px to deal with it ?
Yes we did and by pushing it we simply added it the other end.
Related
I have a flexbox container with scrolling along the x axis. It scrolls properly, but for some reason, many items within the container are hidden to the left of the screen, outside of the display. I have no idea why and am looking to make it such that the first element in the list is the first element seen in the leftmost box of the flexbox.
.home-carousel-cards {
display: flex;
flex-direction: row;
overflow-x: auto;
flex-shrink: 0;
margin: 0 -1px;
justify-content: center;
}
.home-item-card {
width: 241px;
min-width: 220px;
height: 300px;
background: white;
border-radius: 16px;
cursor: pointer;
margin: 0 1px;
border: 1px solid black;
}
The result:
The blue highlighted div is the first visible element. As you can see, the first shoe actually seen is certainly not the first element in the list, and all of the previous elements are not visible. I want the user to scroll right to the end of the list but can't get past this.
I have a div element (shown with red border in the image below), which I want to be able to fit in its parent div when the window is resized and not fall into the next line (the parent is the one with the green border).
I want the red div to have a starting width: 949px (in my current screen) in order to fit the entire space available as shown in the image, but be resizable, so that it doesn't fall into the next line if width: 949px is to much to fit.
In essence, I want it at all costs to cover the area it covers in the image even if in a narrower screen that means it will be like 10px wide.
How can I achieve this? Any solution using CSS, JavaScript or jQuery will be gladly accepted.
The image:
CSS:
#parent {
text-align: center;
width: 90%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: inline-block;
}
#child1-row2 {
text-align: left;
vertical-align: middle;
width: 288px;
display: inline-block;
}
#child2-row2 {
text-align: left;
vertical-align: middle;
width: 288px;
position: relative;
margin: 0 25px 0 25px;
display: inline-block;
}
#child3-row2 {/* The one with the red border */
vertical-align: middle;
height: 452px;
width: 949px;
overflow: hidden;
position: relative;
display: inline-block;
}
You can use flexbox to do this by using the flex-grow property.
HTML :
<div id="main">
<div id="box1">1</div>
<div id="box2">2</div>
<div id="box3">3</div>
</div>
CSS :
#main {
display: flex;
flex-flow: row;
width:100%;
min-height:50px;
}
#box1{
background-color:red;
width:100px;
}
#box2{
background-color:blue;
width:100px;
}
#box3{
background-color:green;
flex-grow: 1;
}
Here is a working JSFiddle
You can use css calc function for this. Support for calc seems to be quite good now.
As you have mentioned, the left side divs are of fixed width, say 120px each. Also suppose the margin between them is 30px. So, the total width left for your red div is 100% - (2*120 + 2*30)px i.e. (100% - 300px ).
#red-div
{
width: calc(100% - 300px);
}
Add % width or you can do following :
$(window).resize(function() {
var window_width = $(window).width();
var w1_width = $('.div1').width(); // The first element width
var w2_width = $('.div2').width(); // The second element width
var main_div_width = window_width - (w1_width+w2_width+gutter[i.e margin between all 3 elements]);
$('.main_div_width').css('width', main_div_width);
});
My Goal:
Here is what I'm trying to accomplish. We have an list of categories that appear on a page. The number of categories is unknown. The description can be pretty much any size... yet we want a uniform look. So, we are using the dotdotdot plugin to put ellipses on the paragraphs. When you hover over the item, it should expand the description and show the full text.
I want that hover to float or overlay whatever is below it. Due to some of my layout items (see my NOTE below) my sccontainer element doesn't have a set height. It's dynamic based on the content... with a max-height set.
When I change that height to AUTO in the hover event (which causes the text to flow down and displays all the content), I lose the background on the sccontainer element.
Some pertinent CSS:
.sccontainer { width: 280px; zoom: 1; float: left; margin: 5px 10px; padding: 0; border: 1px solid #8697a1; -moz-border-radius: 5px; border-radius: 5px; -moz-box-shadow: 0 0 6px #777; -webkit-box-shadow: 0 0 6px #777; box-shadow: 0 0 6px #777; -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=6, Direction=90, Color='#777777')"; filter: progid:DXImageTransform.Microsoft.Shadow(Strength=6, Direction=90, Color='#777777'); position: relative; background: #fff url(http://imagecss.com/images/background.jpg) repeat-x left top; }
.sccontainer .parent { position: absolute; width: 270px; }
.sccontainer .image { margin: 5px; float: left; }
.sccontainer .image img { width: 48px; }
.sccontainer .icon { margin: 0; }
.sccontainer p { margin: 8px; padding: 0; max-height: 145px; }
.sccontainer h1 { line-height: 24px; display: inline-block; vertical-align: middle; width: 200px; height: 48px; padding: 0; margin: 5px 0 0 0; overflow: hidden; }
.sccontainer h1 a { padding: 0; font-size: 24px; color: #fff; font-weight: normal; }
.sccontainer .content { position: relative; height: 210px; padding: 0 5px; font-size: 15px; line-height: 22px; width: 270px; }
.sccontainer a:hover { text-decoration: underline; }
.sccontainer.hover { height: 250px; }
.sccontainer.hover .content { height: auto; }
.sccontainer.hover .content p { min-height: 135px; max-height: none; }
jsFiddle:
Here is a jsFiddle version of what I have right now. You can see this in action, if you hover over the text in the blue box. It's a bit large, so I used jsFiddle instead of putting all the bits here code tags...
http://jsfiddle.net/ztMM5/1/
And here is a mockup of what I'd like to see. Method 5a expands slightly to show the full content.... yets overlaps the red line. None of the other items move around or are affected.
NOTE: Sorry for the size of things. I've trimmed it down about as much as I can. Also, I am modifying an existing intranet website... it's 3rd party, so I have limited control of the source code - hence the table usage. :(
What I've Tried/Researched:
I believe the issue stems from the fact that my sccontainer item is floating, and doesn't have a height specified. That's why the image disappears.
I had a version that kept the background... but the sccontainer box didn't resize like we need... the text just overflowed it... rather ugly.
I don't know enough CSS to make this all work right. I'm not adverse to using jQuery to do more if needed.
I did work on a version that handled most of the hover using the :hover stuff... but it didn't work quite as well as the jQuery approach.
This answer may not solve your specific problem but it may help others with a similar scenario (working with tables makes difficult to render a clean layout in most cases.)
I ran into this issue before and this is how I solved it. It basically relies in an html nested div structure to achieve the expandability of the content without affecting the floating layout of the near elements :
<div id="wrapper" class="cf"><!--wrapper with border and CLEARED-->
<div class="sccontainer"><!--position relative-->
<div class="inner"><!--position absolute-->
<div class="content"><!--position relative-->
<!-- my content here -->
</div>
</div>
</div>
<!-- more containers etc-->
</div><!--END wrapper-->
First, we are going to apply the infamous clear-fix hack to the #wrapper container (use your preferred method):
.cf:after {
visibility:hidden;
display:block;
content:"";
clear:both;
height:0
}
* html .cf {
zoom:1
}
/* IE6 */
*:first-child+html .cf {
zoom:1
}
Then the style for the .sccontainer container :
.sccontainer {
width: 280px; /* or whatever - could be % for responsiveness */
padding-bottom:200px; /* any value to give height without using height ;) */
position: relative;
float: left;
margin: 5px 10px; /* or whatever */
overflow: hidden; /* this is important to keep all same height and big content out of sight */
z-index: 1; /* this is important too, see later */
background: white url("imagebackground.jpg") 0 0 repeat-x; /* need to explain? */
}
Then the .inner container, which actually will help to keep the layout in order if we hover the elements
.inner {
position: absolute; /* please don't move */
width: 100%; /* to fill the whole parent container */
height: 100%; /* same */
}
And the content :
.content {
position: relative;
background: white url("imagebackground.jpg") 0 0 repeat-x; /* not redundant though */
width: 100%; /* helps to fill the gaps with small content */
height: 100%; /* same, specially if using image backgrounds */
/* other styles, etc */
}
NOTE: we should apply same border-radius properties to the three containers and box-shadow to .sccontainer and .content for consistency
Now, what happens when we hover ?
.sccontainer:hover {
overflow: visible; /* show the full content */
z-index: 999; /* place me on top of the others if needed (which lower z-index, remember?) */
}
.sccontainer:hover .content {
height: auto; /* as it really is, including background image */
}
NOTES : this effect will happen regardless if the content's height is smaller than the parent container's height. You may not like the effect mostly if you are using borders and shadows (could be shown as smaller box inside the parent container) so we could add an extra class to .sccontainer like
<div class="sccontainer withhover">
and apply the hover effects only if that class exist like
.sccontainer.withhover:hover {
overflow: visible;
z-index: 999;
}
... and use a bit of jQuery to remove that class for shorter content, so it won't be affected :
jQuery(document).ready(function ($) {
$(".sccontainer").hover(function () {
var $contentHeight = $(this).find(".content").height();
if ($(this).innerHeight() > $contentHeight) {
$(this).removeClass("withhover");
}
});
});
See JSFIDDLE
I am following MVC approach where you can keep some contents static .i.e. header , footer , sidebar etc using layout.In my view, i want to make header and side-bar fixed while user scroll-down the page. Any help ?
Use position : fixed for your header div and sidebar div.
You could definitely cleanup the sidebar and fixed positioning, but this demo seems to work (quick mockup only). You'd need to add the CSS to your stylesheet, and then create partials for the header, sidebar and main content window.
In the CSS (below), you'd need to adjust some properties to make sure everything aligns properly as you're setting up your design.
* { box-sizing: border-box; }
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
padding:10px;
background-color: #eee;
border-bottom: 1px solid #ddd;
}
.container { padding-top: 32px; } /* Adjust this value based on height of .header */
.main {
width: 70%;
margin-left: 30%;
padding-left: 20px;
}
.sidebar {
position: fixed;
top: 41px; /* Adjust this value based on height of .header and any additional padding */
bottom: 0;
width: 30%;
overflow-y: scroll;
}
There's a mysterious whitespace along the right of my site in firefox (on both PC and Mac, latest versions) and I can't for the life of me figure out what's causing it.
This is what it looks like -
I've been searching the CSS for ages now trying to figure out if it's some margin or padding issue but I can't find anything.
Also, if I remove the div ID 'slider3' the issue seems to disappear, yet I can't figure out how this div is causing the whitespace, since it has no CSS applied to it - it's simply a container.
Here's my site http://www.simplerweb.co.uk
Here's some relevant code so the answer is useful for people later on.
<div class="fullw">
<div class="sliderleft"></div>
<div class="sliderright"></div>
<div id="slider3">
<div class="quote">
<div class="centmid">
<h1 class="fronth">Hello</h1>
<h2 class="frontp">Welcome to Simpler Web</h2>
<h2 class="frontp2">We're an Edinburgh based Web<br> Design Agency</h2>
</div><!-- end div centmid -->
</div> <!-- end div quotes1 -->
<div class="quote2">
<div class="centmid">
<h2 class="frontb">We make wonderful, cross platform <br> accessible Websites </h2>
</div> <!-- end div centmid -->
</div> <!-- end div quotes2 -->
<div class="quote3">
<div class="centmid">
<h2 class="frontc">We can translate your ideas into reality </h2>
</div> <!-- end div centmid -->
</div><!-- end div quotes3 -->
</div> <!-- #slider3 -->
</div>
CSS
/* The following styles are essential to the slider's functionality */
.plusslider {
overflow: hidden;
position: relative;
padding-top: 140px; /* The height / width of the slider should never be set via the CSS. The padding increases the slider box-model while keeping it dynamic */
}
.plusslider-container { position: relative; }
/* Slides must have a set width - even though they may be dynamic. If no width is set on <img> slides, the default image size will be assumed */
div.child { width: 480px; }
.plusslider .child { float: left; }
/* PlusFader Specific (not needed with plustype:slider */
.plustype-fader .child { display: none; position: absolute; left: 0; top: 0; }
.plustype-fader .current { z-index: 5; }
/* End PlusFader Specific */
/* No-javascript fallback -- change "#slider" and "#slider2" identifiers as needed for your html */
#slider > * { display: none; }
#slider > *:first-child, #slider2 > *:first-child { display: block; }
/* End no-javascript fallback */
/* End essential styles*/
/* The following styles are not essential for slider functionality. They are specific to the example content.
It is important to note that the fading effect does not work correctly with non-image content unless that
content area has a solid background (either a background image or a background-color, but not transparent).
Slides to not have to be the same width or height, but if you'd like a consistent width and/or height, make sure to set that within the CSS! */
#slider .slide1 { padding-left: 40px; padding-right: 40px; margin-left: 0; margin-right: 0; }
#slider .slide1 { height: 210px; padding-top: 20px; padding-bottom: 20px; margin-top: 0; margin-bottom: 0; }
.slide1 { height: 500px; padding: 20px 40px; }
.slide1 h2 { color: #fff; font-size: 20px; margin: 0 0 20px 0; text-align: left; }
.slide1 p { border-left: 3px solid #fff; color: #fff; padding: 0 0 0 10px; }
.quote, .quote2, .quote3 { height:400px; padding: 20px 0; width: 980px; width: 100%; position: relative; }
.quote { background-image: url(../images/weare.png); background-position: center; background-repeat: no-repeat; }
.quote2 { background-image: url(../images/headlogosandroid.png); background-position: center; background-repeat: no-repeat; }
.quote3 { background-image: url(../images/ideafront.png); background-position: center; background-repeat: no-repeat; }
.plusslider a img { border: none; } /* Prevent blue borders in IE (not only does it look ugly, but it messes up spacing which breaks the "slider" type */
.plusslider-pagination { position: absolute; left: 0; bottom: 0; }
.plusslider-pagination li { float: left; list-style: none; margin-left: 5px; }
#slider3 {margin: 0; padding: 0;}
You have (in FF) exactly 17px extra width that is exactly the width of the browser scrollbar.
Your starting (initial) loading black screen (that animates) leaves a glitch of 17px:
cause it's animation maintains the DOM width that equals the screen width without the right scrollbar (100% screen width).
After the page is fully loaded and the scrollbar is added to the page, it actually adds the extra 17px (to the 100%) width that were maintained by the Loading animation.
Hope I put you in the right direction.
By the way, try to add:
html {
overflow-y: scroll;
}
and - if still needed - adjust the loading element width as I mentioned before.
Add this:
body{
overflow-x: hidden;
}
Problem solved. (temporarily)
So where is the problem?
It is at your <div> with the classes plusslider slider3 plustype-slider. You are constantly setting an incorrect width to it. You have to subtract the scrollbar width.
You can also try to do this: Padding: 0px(or whatever) 17px; and margin: 0px(or whatever) -17px; now your whitespace at the sides are gone.