Keep Text Fixed on One Line - Mobile Slide In Menu CSS - html

I am wondering if there is a style that keeps the text within a div locked into a straight line no matter what the width of the container is? (No stacked text)
See I have a slide-in menu that is working nicely, the buttons look great, but there's just one thing that's visually offputting and it's that the text is stacked up as it slides out and then flattens out as the width of the container is increased to full screen.
Here's the HTML of a menu item:
<div class="navigation-menu-slide-in-10">
Account
</div>
And here's the CSS of the menu item:
.navigation-menu-slide-in-10 {
width: 100%;
height: 6vh;
background-color: transparent;
display: flex;
justify-content: left;
align-items: center;
font-family: bahnschrift;
font-size: 28px;
font-weight: bold;
}
.navigation-menu-slide-in-10 a {
padding-left: 24px;
text-decoration: none;
color: #ffffff;
}
As for how the menu unfolds, here's the Javascript. The button is clicked and then goes out of visual existence. Then the other button is made visible within my slide-out-menu. Then the slide-out-menu is made visible. And then is increased to 100% width with a transition delay which acts as an animation.
function mobileNavigationButtonOn() {
document.getElementById("mobileNavigationButtonOff").style.display = "none";
document.getElementById("mobileNavigationButtonOn").style.display = "flex";
document.getElementById("mobileNavigationMenuSlideIn").style.visibility = "visible";
document.getElementById("mobileNavigationMenuSlideIn").style.width = "100%";
}
Oh, and I guess the CSS for the slide-in-menu might be pertinent too. Here is that:
.navigation-menu-slide-in {
width: 0%;
height: 100%;
background-image: linear-gradient(to right, #ff3300, #ff7700);
position: fixed;
visibility: hidden;
transition-duration: 0.6s;
transition-property: width;
overflow-x: hidden;
z-index: 3;
}
Yeah, so I'm looking for a way to keep the text fixed into a straight line. Thanks.

I found the style that works if anyone is having this same issue...
white-space: nowrap;

Related

Preserve dropdown hover when circular button and dropdown are separated by a gap

The main issue is caused by a button being circular. But I really want a circular button, which is leading to hovering problems!
All I want is to have a circular <a> button that when hovered-over will reveal another element below it, like a div or another a tag. These two elements are separated by a gap.
Then I should be able to move my mouse down and hover over the revealed element and click on it or whatever. But of course if you unhover the original <a> then the other element will disappear, especially since there is a gap between the two elements. What is the best way to make it so that I can move my mouse from element 1 to element 2 without element 2 vanishing during mouse travel?
Ideally this shouldn't require JS.
I've created a basic setup for this so far to get started:
body {
padding: 30px;
height: 100vh;
}
#myBtn {
background-color: grey;
padding: 20px;
border-radius: 50%;
}
#hoverInfo {
display: none;
margin-top: 40px;
background-color: green;
width: 100px;
height: 50px;
}
#myBtn:hover + #hoverInfo, #hoverInfo:hover {
display: block;
}
<a id="myBtn" href="/">
button
</a>
<a id="hoverInfo" href="/">hover info</a>
Here's an explanation of an old solution attempt of mine:
My first solution to stop element 2 from vanishing upon downward movement of the mouse was to put an invisible hoverable element between elem 1 and 2 which would keep elem 2 active while the mouse moves down to it. And this would work great, IF all elements were rectangular. But my elem 1 is circular!
This means that there is literally one single pixel of contact between the middle hover buffer element and elem 1 because there are those circular "corner" gaps between elem 1 and the invisible middle element. So whenever you move your mouse down, you are still going to miss that middle hover element 99% of the time.
And you can't put it behind elem 1 either to fill in those circular "corners" because the circular element has a bounding box that you can only see in inspect element and this bbox prevents you from filling up those "corners" with an area that actually interacts with the mouse, therefore making this solution useless. It's quite confusing in my explanation but try it out if you manage to implement this "solution".
The first solution to come to mind is wrapping the circular button into a parent div, which will be the div that will activate the hover effect. This way, you can add padding-bottom to imitate the gap look while still making the "gap area" trigger the hover effect. In the snippet below, I made the wrapper div have a red background so you can see how it works. If you remove the red background, it should function as intended.
https://codepen.io/xenvi/pen/yLONOEa
body {
padding: 30px;
height: 100vh;
}
.buttonWrapper {
display: inline-block;
margin-bottom: 40px;
background: red;
}
#myBtn {
background-color: grey;
padding: 20px;
border-radius: 50%;
}
#hoverInfo {
display: none;
background-color: green;
width: 100px;
height: 50px;
}
.buttonWrapper:hover+#hoverInfo,
#hoverInfo:hover {
display: block;
}
.buttonWrapper:hover {
margin: 0;
padding-bottom: 40px;
}
<div class="buttonWrapper">
<a id="myBtn" href="/">
button
</a>
</div>
<a id="hoverInfo" href="/">hover info</a>
You can solve this easily using a pseudo element that will make the hoverable area bigger and that you activate only on hover:
body {
padding: 30px;
height: 100vh;
}
#myBtn {
background-color: grey;
padding: 20px;
border-radius: 50%;
position:relative;
}
#myBtn:before {
content:"";
display:none;
position:absolute;
top:90%;
left:0;
right:0;
height:28px;
}
#hoverInfo {
display: none;
margin-top: 40px;
background-color: green;
width: 100px;
height: 50px;
}
#myBtn:hover::before {
display:block;
background:rgba(0,0,255,0.2); /* to illustrate */
}
#myBtn:hover + #hoverInfo, #hoverInfo:hover {
display: block;
}
<a id="myBtn" href="/">
button
</a>
<a id="hoverInfo" href="/">hover info</a>

Hover effect make weird behavior on mobile devices

I have very weird problem. So let try explan you. Im developing web application thats going to be used on mobiles. Everything is going well, but i hit a very nasty problem. The app is simple, we have Welcome screen from where you have just on button called Get Strated (near in the middle of screen), after clicking this button app switch to page with listing products in 2x2 grid. Every product has hover effect which blur the image and show name and price. So i hope everything till now sounds good? The problems ocurs when user clicks Get Started and the page render after that automaticly has the item which is on the same place as button 'hovered' which seems strange behavior because you won't to see any of those items pre-selected.
Step one:
main welcome screen when the user clicks Get Started button:
Step two: user has clicked Get Started and goes to products list with one item marked as selected/clicked because of hover effect
Here is the html/css, just an regular hover effect thats add blur and show prodcut name&price:
<ul className="list-products">
{productsStore.menuProducts.filter(p => p.sectionId == productsStore.activeSectionId).map((product, index) => {
return (
<li key={index} onClick={() => handleOnProductClick(product.id)}>
<button>
<small style={{ backgroundImage: "url(" + getDefaultImage(product.image) + ")" }}></small>
<strong id={product.id}>
<span>
{product.name}
<em>{product.price.toFixed(2)}</em>
</span>
</strong>
</button>
</li>
)
})}
</ul>
.list-products { display: -moz-flex; display: -ms-flex; display: -o-flex; display: flex; flex-wrap: wrap; }
.list-products li { width: 50%; position: relative; padding-bottom: 50%; border-bottom: 1px solid #252525; }
.list-products li:nth-child(odd) { border-right: 1px solid #252525; }
.list-products li button { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #fff; border: 0; border-radius: 0; }
.list-products li button strong { position: absolute; top: 0; left: 0; width: 100%; height: 100%; font-weight: 400; background: rgba(0,0,0,.3); opacity: 0; }
.list-products li button:hover strong { opacity: 1; }
.list-products li button strong { display: -moz-flex; display: -ms-flex; display: -o-flex; display: flex; align-items: flex-end; justify-content: center; padding: 10px; }
.list-products li button span { display: inline-block; font-size: 18px; text-align: left; width: 100% }
.list-products li button span em { font-style: normal; display: block; }
.list-products li button small { background-size: cover; background-position: center; position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.list-products li button:hover small { filter: blur(2px); -webkit-filter: blur(2px); }
I have forgot to mention that I'm using React. Also this behaviour couldn't be reproduced on PC even with mobile view enabled. It is possible only on mobile devices and I have tested it on iphone with safari browser.
What i think is happening: since we are on mobile device, hover effect triggers when users click somewhere on the screen and till the user click onther place, hover keep staying there and since we clicked Get Started (right side of button), the browser thinks we are hovering there and thats why it show as hovered? But now whats the solution here?
Your guess is exactly right. Hover effects do not work correctly on mobile. When a user clicks on the element it quickly triggers the hover effect before taking them to the next link. Sometimes phones will cache that triggered the hover effect and make it always appear that way. Instead of hover effects, you would only want to use on-click effects for mobile. Maybe one day our phones will support this better.

Why doesnt this hover trigger text animation?

Trying to add a hover in a CMS program that only allows internal css. Please note that, while there is no head tag, the CMS recognizes tags and automatically places them in the .
I've tried exporting as html to work through the issue but so far no luck. Tried using hierarchy by placing the resting state as H1 and hover state as a div class and as an ID. This is to be used through EKTRON CMS running html5 with no accessibility to js.
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
h1 {
margin: 0;
padding: 0;
}
h1 span {
display: inline-flex;
color: #1C7CB3;
}
h1 span:nth-child(even) {
overflow: hidden;
transition: ease 0.5s;
color: purple;
letter-spacing: -1em;
}
h1:hover span:nth-last-child(even) {
letter-spacing: 0;
}
<h1>
<span>F</span><span>lorida</span>
<span>I</span><span>nstitute</span>
<span></span><span>of</span>
<span>E</span><span>ducation</span>
</h1>
I expected the text to animate but the text stays static.
In the hover effect you are using the :nth-last-child(even) selector. This will select every even element starting from the last. That is it will have it's first odd element being <span>ducation</span> and it's first even being <span>E</span>. You instead would want to use the :nth-child(even) to select from the start.
h1:hover span:nth-child(even)
{
letter-spacing: 0;
}

Is it possible to change this div color on scroll using purely CSS?

Thanks for taking the time to read my post.
So I've started freelancing recently (CSS and HTML) and I've found my first difficulty.
Look at the green bar (Its a fixed div), its green for testing porpuses, but client wants it to be transparent when on top of this orange background...
...But switch to another color when on top of this white background (So the letters can be seen)
Is this possible to do with CSS? If so, how do I do it?
Thanks again!
Pure css does not currently have any amount of responsiveness to what is and is not onscreen. So, the short lame answer is "not with just css."
That being said, it's very easy to do this with js.
The event you'll be looking for is scroll event.
From there you can add/remove a class for styling.
Something like this:
// wait for document.addEventListener("DOMContentLoaded");
const myHeader = document.getElementById("MyHeader");
window.addEventListener("scroll", () => {
const scrollPos = window.scrollY;
if (scrollPos ... add your logic here) {
myHeader.classList.add("scrollIsThing"); // this is the css class you'll target
} else {
myHeader.classList.remove("scrollIsThing");
}
});
Sorry there's no good css way to do this.
It is "kind of" possible to do this just with css if you can accept some html markup duplication. You can split the fixed header into two layers, one for white text, one for background, and using z-index you can sandwich the content between these two header layers (in case of a colorful content), in which case only the white text would be visible, and position the white content below the header background. A sample of such behavior is shown below:
.header {
height: 50px;
background: transparent;
position: fixed;
top: 0;
width: 100%;
color: white;
font-family: sans;
text-align: center;
line-height: 50px;
z-index: 3;
}
.header.header-background {
background: teal;
z-index: 1;
}
.body1 {
height: 120vh;
background: orange;
z-index: 2;
position: relative;
}
.body2 {
height: 120vh;
background: #eee;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
<div class="header">
White text
</div>
<div class="body1"></div>
<div class="header header-background">
</div>
<div class="body2"></div>

How do I make my hamburger menu appear directly under my hamburger icon?

I want to have to click on a hamburger menu icon and then have the list display beneath my icon. I set up my hamburger menu icon with this style
.menu-btn div {
position: absolute;
left: 100%;
top: 64%;
padding-right: 8px;
margin-top: -0.50em;
line-height: 1.2;
font-size: 18px;
font-weight: 200;
vertical-align: middle;
z-index: 99;
}
.menu-btn span {
display: block;
width: 20px;
height: 2px;
margin: 4px 0;
background: #989da1;
z-index: 99;
}
The menu of options taht should appear after you click on the hamburger menu is
<div class="responsive-menu">
<ul id="menu">
<li>Vote</li>
<li>Search</li>
<li>About</li>
<li>Log In</li>
</ul>
</div>
but I'm unclear how to set up the style of the hamburger menu so taht it appears directly under the hamburger menu when you click on it. Right now, its appearing centered at the top of the screen -- https://jsfiddle.net/wtp1k57b/1/ . How do I set up such a style?
PS - I'm looking for a solution that doesn't rely on hard-coding numeric (e.g. top: 27px) pixel values. Certainly its good to get things to work in my little Fiddle, but in my broader application I can't guarantee how big or small that hamburger menu will be.
I would like to show a completely different approach without using display: flex.
HTML
Your approach uses too many wrappers in my opinion. You can definitely reduce the amount of divs. Moreover, you should always try to use semantic tags over general tags like div or ul. Consider looking at this article.
Hence, as #scooterlord already mentioned, you should use a button for the hamburger icon. Moreover, I recommend to use a nav instead of a list.
CSS
First of all, you should bundle the attributes for the same selector at the same place for the purpose of improved clarity. You should not have three sections where you apply the universal selector, but combine it into one. Moreover, do not set the box-sizing to a specific value, but rather set it to inherit, so you can always override this value for a specific element without having to do it for all of its children. Furthermore, I do not understand what you want to achieve with margin: 0 auto on all elements and body. It does not make any sense for me.
Since you do not want to use absolute positioning, I would strongly advise you to avoid using pixels as a measuring unit. They behave badly if some people change their default font-size because of poor eyesight or other reasons. Instead, consider to apply relative units like rem, em or %. By setting the root element's font-size to 62.5% you are still able to calculate as if you were using pixels (1rem = 10px).
As I already mentioned, I avoided to use display: flex for such a trivial thing. I do not understand why it should be used at this point. Therefore, I also had to change the positioning of the menu button. The navigation could be easily positioned using percentages for top and left.
As a side note: You should really try to only post the relevant CSS code - the first step for me was to remove all the irrelevant parts of it.
Final Solution
This is my final solution without Flexbox, without fixed sizes and without absolute positioning using px:
$('.menu-btn').click(function() {
$('nav').toggleClass('nav-open');
});
* {
margin: 0;
padding: 0;
box-sizing: inherit;
}
html {
font-size: 62.5%;
}
body {
font: 1.6rem/1.4 Benton Sans, -apple-system, BlinkMacSystemFont, Roboto, Helvetica Neue, Helvetica, Tahoma, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
}
header {
width: 100%;
background-color: orange;
text-align: center;
padding: 1rem;
position: relative;
}
nav {
display: none;
width: 30rem;
padding: 5rem;
background-color: #ededed;
position: absolute;
right: 5%;
top: 100%;
}
.nav-open {
display: block;
}
nav a {
display: block;
width: 100%;
text-align: center;
padding: 1.4rem 1.6rem;
text-decoration: none;
cursor: pointer;
font-size: 2.2rem;
color: #000;
}
nav a:hover {
background-color: #111;
color: #fff;
}
.menu-btn {
position: absolute;
right: 5%;
top: 50%;
margin-top: -1.1rem;
display: inline-block;
cursor: pointer;
border: none;
outline: none;
background-color: transparent;
}
#media only screen and (min-width: 500px) {
.menu-btn, nav {
display: none !important;
}
}
.menu-btn span {
display: block;
width: 2rem;
height: 0.2rem;
margin: 0.4rem 0;
background: #989da1;
z-index: 99;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<h2>Page Title</h2>
<button class="menu-btn">
<span></span>
<span></span>
<span></span>
</button>
<nav>
Vote
Search
About
Log In
</nav>
</header>
Or see this fiddle.
Use the css properties: top and right to set the position of the element under your icon.
#menu
{
position: absolute;
top: 48px;
right: 2px;
background: #ededed;
list-style-type: none;
}
Use this CSS for your menu - no margin, and the position defined by the top and right settings:
#menu {
position: absolute;
width: 300px;
margin: 0;
padding: 50px;
background: #ededed;
list-style-type: none;
-webkit-font-smoothing: antialiased;
top: 50px;
right: 0;
}
https://jsfiddle.net/meuexde6/
I left out the transition for the testing, but you should basically animate the right parameter from -100px to 0 to achieve what you seemed to have in mind.
ADDITION AFTER COMMENT:
To define the position of the menu in relation to the button, you have to apply position: relative to their common parent element, .mobile-nav. The position values of an element with position: absolute always relate to the first ancestor which has position: relative.
I changed the values in my updated fiddle accordingly to these:
#menu {
position: absolute;
width: 300px;
margin: 0;
padding: 50px;
background: #ededed;
list-style-type: none;
-webkit-font-smoothing: antialiased;
top: 40px;
right: -32px;
}
Updated fiddle: https://jsfiddle.net/meuexde6/1/
If you really want the menu to stick directly to the button (hard to say - it has no borders), just adjust the top and right values as needed.
HTML5 Semantic Elements.
details > summary {
padding: 2px 6px;
width:12px;
border: none;
list-style: none;
}
details > summary::-webkit-details-marker {
display: none;
}
ul{
list-style: none;
margin-left:0;
padding-left:0;
}
<details>
<summary>☰</summary>
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
</details>
So, here goes. I know you are asking for a solution to a specific problem, I solved it alright, but I couldn't help noticing that you are struggling with your code. You must simplify the way you think and your code will become leaner. The purpose of this forum is to help others become better, right? :)
HTML
It is good practice to keep the menu toggle button OUTSIDE of the menu - will solve a lot of issues - check below.
It is not semantically right to use anything else rather than a button for the toggle function, so, why not use a button here? I also removed unnecessary clutter from your code, like some divs and the id - the id could be traded with the class, your call. I also removed .mobile-nav because it is not needed at all.
<button class="menu-btn">
<span></span>
<span></span>
<span></span>
</button>
<div class="responsive-menu">
<ul id="menu">
<li>Vote</li>
<li>Search</li>
<li>About</li>
<li>Log In</li>
</ul>
</div>
CSS
I absolutely positioned the menu-btn on the top right corner, and gave it a width equal to the #pageTitle height (which I set at 50px - a gold standard) to keep it rectangular; it should be a rule of thumb that the toggle buttons are rectangular and always the same height as the top navigation bar - in this case the before-mentioned id. The same I did for the .responsive-menu. I absolutely positioned it as shown below. The changes allowed me to remove a lot of css styling - now obsolete - like for example the absolute positioning of the ul menu inside the .responsive-menu.
.menu-btn {
position:absolute;
display:block;
right:0;
top:0;
width:50px;
height:50px;
background:yellow;
border:none;
padding:16px;
}
.responsive-menu {
position: absolute;
top: 50px;
right: 0;
display: none;
}
Javascript
By years of practice I realized that the most efficient way to toggle a menu instead of adding and removing classes is to add a class on the body tag; this can help heaps if you want to restyle anything else on the page depending on wether your menu is opened or not.
$('.menu-btn').on('click', function() {
$('body').toggleClass('responsive-menu-open');
});
Here is a working jsfiddle: https://jsfiddle.net/scooterlord/4atafhge/
I could have done a lot of other things in order to simplify the code even further - remove unnecessary ids and classes since most elements are considered unique and could be targeted using descendant classes, eg .responsive-menu ul, etc. After a lot of practice, you'll manage to think simpler and produce code with a smaller footprint.
Edit: Concerning the fact that you don't like the absolute pixels for alignment here is a trick.
Giving a fixed height to the parent container, equal to the toggle button's -in this case '#pageTitle' and setting its position to relative allows you to use top:100% to properly place the responsive menu exactly below the button (which is essentially the same height):
#pageTitle {
display: flex;
height: 50px;
position:relative;
}
.responsive-menu {
position: absolute;
top: 100%;
right: 0;
display: none;
}
Here is an updated fiddle: https://jsfiddle.net/scooterlord/4atafhge/1/
Edit: Natalia, I gave it some thought and here is what I came up with. I created an absolutely positioned .menu-wrapper, inside of which I placed the button and the responsive menu with float:right and no positioning - aka they are positioned statically. No more pixel values! YAY!
.menu-wrapper {
position:absolute;
top:0;
right:0;
}
.menu-btn {
float:right;
...
}
.responsive-menu {
float:right;
clear:both; // to clear the .menu-btn and sit exactly below it
...
}
Here is a working fiddle: https://jsfiddle.net/scooterlord/4atafhge/2/