Stop :after element from jumping to the next row on wrap - css

I have some beautiful CSS:
$itemHeight: 40px;
$arrowModifier: 8;
$pageBackgroundColor: $color-gray-50;
.processBar {
display: flex;
flex-wrap: wrap;
&_item {
display: inline-block;
background: $color-gray-200;
height: $itemHeight;
position: relative;
flex-grow: 1;
text-align: center;
line-height: $itemHeight;
text-decoration: none;
color: $color-text;
padding-left: 10px;
padding-right: 10px;
&:hover {
text-decoration: none;
color: $color-text;
}
&-default {
&:hover {
background: $color-light-gray;
}
}
&-selected {
background: $color-white;
}
&:before,
&:after {
display: inline-block;
content: "";
border-style: solid;
position: absolute;
}
&:first-child {
&:before {
left:0;
border: none;
}
}
&:not(:first-child) {
&:before {
left:0;
border-color: transparent transparent transparent $pageBackgroundColor;
border-width: $itemHeight/2 0 $itemHeight/2 $itemHeight/$arrowModifier;
}
}
&:last-child {
&:after {
right: 0;
border: none;
}
}
&:not(:last-child) {
&:after {
right:0;
border-color: $pageBackgroundColor transparent;
border-width: $itemHeight/2 0 $itemHeight/2 $itemHeight/$arrowModifier;
}
}
}
}
Here is the HTML that uses it:
<div class="processBar">
Label
Label
Label
Label
Label
Label
</div>
Here is what it does:
But at a certain size the :after elements can jump down, as seen here:
I don't understand why that is happening. How can I stop it from happening?

The ::before and ::after pseudo-elements on a flex container are considered flex items.
The ::before pseudo is the first item. The ::after pseudo is the last. So you have to think of them as siblings of the other flex items.
You can try using the order property to re-arrange items to achieve the effect you want.

What CSS pre-processor is this? I used every pre-compiler on CodePen and got errors from the $variables so I removed them and filled them in with whatever. Is this Stylus? Anyways, besides the variables being removed and some color changes, the only significant change is that I changed flex-wrap:wrap to flex-wrap:nowrap.
SNIPPET
.processBar {
display: flex;
flex-wrap: nowrap;
}
.processBar_item {
display: inline-block;
background: #c8c8c8;
height: 40px;
position: relative;
flex-grow: 1;
text-align: center;
line-height: 40px;
text-decoration: none;
color: #000;
padding-left: 10px;
padding-right: 10px;
}
.processBar_item:hover {
text-decoration: none;
color: red;
}
.processBar_item-default:hover {
background: #808080;
}
.processBar_item-selected {
background: cyan;
}
.processBar_item:before,
.processBar_item:after {
display: inline-block;
content: "";
border-style: solid;
position: absolute;
}
.processBar_item:first-child:before {
left: 0;
border: none;
}
.processBar_item:not(:first-child):before {
left: 0;
border-color: red;
border-width: 20px 0 20px 5px;
}
.processBar_item:last-child:after {
right: 0;
border: none;
}
.processBar_item:not(:last-child):after {
right: 0;
border-color: tomato;
border-width: 20px 0 20px 5px;
}
<div class="processBar">
Label
Label
Label
Label
Label
Label
</div>

Related

Can a child absolute element go under parent inline element

I want to make a tab style so the bottom of the tab doesn't have an underline. To do this I thought I could set bottom border color of tab and then make child menu go underneath.
I am not sure if that is possible though.
This excerpt is taken from site, it is done like this as the child menu is usually shown on hover.
body {
background-color: #000;
}
.desktop-menu {
color: #fff;
list-style: none;
}
.desktop-menu a {
color: #fff;
text-decoration: none;
}
.desktop-menu > li {
background-color: blue;
width: 60px;
margin-left: 25px;
border: 1px solid #fff;
border-bottom-color: blue;
padding: 10px;
position: relative;
z-index: 20;
}
.desktop-menu ul {
background-color: blue;
z-index: 10;
width: 200px;
display: flex;
position: absolute;
top: 100%;
left: -1px;
flex-direction: column;
list-style: none;
margin: 0;
padding: 10px 20px;
padding-top: 15px;
border: 1px solid #fff;
background-color: darkblue li;
padding-bottom: 15px;
}
.desktop-menu .has-sub:hover {
border: 1px solid #fff;
}
.desktop-menu .has-sub:hover ul {
display: flex;
}
<ul class="desktop-menu">
<li class="has-sub">Products
<ul>
<li>Product name 1</li>
<li>Prod name 2</li>
</ul>
</li>
</ul>
I am trying to remove this white line:
What is best method to achieve this?
Just a hack but it works.
.desktop-menu > li {
position: relative;
// ...
}
.desktop-menu > li::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 1px;
width: 100%;
background-color: blue;
}
.desktop-menu ul {
display: none;
transform: translateY(-1px);
// ...
}
.desktop-menu .has-sub:hover ul {
display: flex;
}
See result in codesandbox.
Note: not suitable if you are working with transparent backgrounds.
Edit: updated the sandbox to proof it works with the hover effect.

Why is my mobile nav menu drawer pushing the site view downwards when it is opened?

Building a mock website for a family member (placeholder photos). When I open the navigation menu, it pushes the screen down instead of simply opening to the right. Seems to translate the view vertically. How can I get it to just open smoothly to the right without pushing the screen view down?
1a) Screen before opening https://i.stack.imgur.com/UfuZi.png
1b) screen when I click nav menu https://i.stack.imgur.com/yfzS3.png
1c) screen when I scroll up after opening the nav menu https://i.stack.imgur.com/9cI5i.png
Here is the css for the navbar:
NAV HEADER CSS
#media only screen and (max-width: 768px) {
body .site-nav__thumb-menu {
position: absolute;
top: 20px;
bottom: unset;
left: unset;
right: unset;
padding-top: 6px;
}
.site-nav__thumb-menu span.icon-menu-label {
display: none;
}
.site-nav__thumb-menu button svg {
color: #000;
box-shadow: none !important;
}
.site-nav__thumb-menu--inactive {
transform: unset;
}
.slide-nav__wrapper {
transform: translateX(-100%) !important ;
background-color: #fff;
}
.slide-nav__dropdown .slide-nav__sublist-header {
text-decoration: none;
}
.slide-nav__overflow--thumb {
width: 100%;
background-color: #000;
height: 100%;
}
.js-menu--is-open .slide-nav__wrapper {
transform: translateX(0) !important ;
}
.site-nav__thumb-menu button {
background-color: unset !important;
padding: 0;
text-align: left;
width: auto;
min-width: auto;
box-shadow: none !important;
}
nav.slide-nav__wrapper .slide-nav {
padding-bottom: 15px;
}
.slide-nav__overflow--thumb {
left: 0;
right: 0;
bottom: unset;
top: 100px;
position: absolute;
max-height: unset;
}
.header-item.mobile-ac.header-item--icons {
flex: unset;
position: absolute;
right: 10px;
top: 8px;
}
header.site-header.small--hide {
display: block !important;
}
.header-wrapper.header-wrapper--overlay {
transition: .5s ease;
}
.header-wrapper.header-wrapper--overlay.sticky {
position: fixed;
width: 100%;
background-color: #fff;
z-index: 99;
}
.header-wrapper.header-wrapper--overlay.sticky .announcement {
display: none;
}
body .header-wrapper--overlay.sticky + .site-nav__thumb-menu {
position: fixed;
top: -18px;
z-index: 9999;
}
.slide-nav a, .slide-nav button {
color: #000;
text-align: left;
z-index: 9999 !important;
}
.slide-nav .search-modal__wrapper {
border: unset;
}
.slide-nav .search-modal__wrapper {
border: unset;
background: #f1f1f1;
padding: 5px 15px;
}
.search-mobc {
padding: 8px 16px;
display: none;
}
nav.slide-nav__wrapper .slide-nav form button {
float: right;
}
nav.slide-nav__wrapper .slide-nav form button svg {
width: 25px;
height: 40px;
}
.slide-nav__overflow {
transition: .5s ease;
}
.slide-nav__overflow--thumb.sticky {
top: 70px;
position: fixed;
z-index: 9999;
}
.slide-nav__link, .slide-nav__sublist-link {
padding: 16px 20px;
}
.slide-nav__overflow--thumb nav.slide-nav__wrapper {
width: 303px;
height: 100%;
overflow-y: auto;
}
.slide-nav a, .slide-nav button {
color: #000 !important;
}
.slide-nav__overflow--thumb .slide-nav__dropdown {
background-color: #fff;
}
.slide-nav__overflow--thumb.js-menu--is-open {
background-color: #000;
height: 100% !important;
}
.slide-nav__wrapper .slide-nav__item {
border-bottom: 1px solid #ccc;
padding: 7px 0;
}
.site-nav__thumb-menu .site-nav__thumb-cart {
display: none;
}
.account-links-m a.slide-nav__link {
border: 2px solid #000;
width: 140px;;
margin: 0 auto;
font-size: 16px;
font-family: Titling !important;
text-transform: uppercase;
display: none;
}
'Slide out menu css'
.slide-nav__overflow--thumb nav.slide-nav__wrapper {
width: 303px;
height: 100%;
overflow-y: auto;
}
.slide-nav a, .slide-nav button {
color: #000 !important;
}
.slide-nav__overflow--thumb .slide-nav__dropdown {
background-color: #fff;
}
.slide-nav__overflow--thumb.js-menu--is-open {
background-color: #000;
height: 100% !important;
}
.slide-nav__wrapper .slide-nav__item {
border-bottom: 1px solid #ccc;
padding: 7px 0;
}
There are several methods to achieve such a thing. I would recommend to remove. the top attribute which would resolve your problem.
What you are doing is :
and what you want is :
Ensuring both your top menu and your floating menu are top:0; should do the work.

Button not laid out against top of relatively positioned container in Firefox

I'm building a toggle switch and the head (button) isn't positioned all the way to the top as I'd expect it to be in Firefox. Works fine in Chrome, so maybe has something to do with default browser styles?
Edit: I know how to make it work, I want to know why it happens.
codepen https://codepen.io/warhammered_cat/pen/qBZYZVy
const toggleSwitch = document.querySelector('.toggle-switch')
const toggleSwitchHead = document.querySelector('.head')
function handleToggle(e) {
toggleSwitch.classList.toggle('active')
}
toggleSwitchHead.addEventListener('click', handleToggle)
* {
box-sizing: border-box;
}
document, body {
margin: 0;
padding: 0;
}
.head {
width: 1.25rem;
height: 1.25rem;
border: 0.125rem solid gray;
border-radius: 50%;
background-color: white;
cursor: pointer;
transition: all 0.4s;
outline: none;
box-shadow: none;
}
.rail {
height: 0.75rem;
width: 100%;
background-color: gray;
border: 0.125rem solid gray;
position: absolute;
top: 0.25rem;
z-index: -1;
border-radius: 0.3rem;
transition: all 0.4s;
}
.toggle-switch {
position: relative;
height: 1.25rem;
width: 2rem;
}
.toggle-switch.active > .head {
background-color: #F7941E;
border-color: #F7841E;
transform: translateX(1rem);
}
.toggle-switch.active > .rail {
border: 0.125rem solid #F7941E;
background-color: white;
}
<div class='toggle-switch'>
<button class='head'></button>
<div class='rail'></div>
</div>
The <button> element is what is specifically being rendered differently in Firefox and Chrome.
If you change the <button> to a <div> the problem fixes itself.
The reason is that the button element is not a block element by default. You have to explicitly set the button to be a block element to get the desired behavior.
.head {
...
display: block;
...
}
try this instead,
Add display:inline-flex; to head class
.head{
display:inline-flex;
}
Click below to see codepen demo
Result :
const toggleSwitch = document.querySelector('.toggle-switch')
const toggleSwitchHead = document.querySelector('.head')
function handleToggle(e) {
toggleSwitch.classList.toggle('active')
}
toggleSwitchHead.addEventListener('click', handleToggle)
* {
box-sizing: border-box;
}
document, body {
margin: 0;
padding: 0;
}
.head {
width: 1.25rem;
height: 1.25rem;
border: 0.125rem solid gray;
border-radius: 50%;
background-color: white;
cursor: pointer;
transition: all 0.4s;
outline: none;
box-shadow: none;
display:inline-flex;
}
.rail {
height: 0.75rem;
width: 100%;
background-color: gray;
border: 0.125rem solid gray;
position: absolute;
top: 0.25rem;
z-index: -1;
border-radius: 0.3rem;
transition: all 0.4s;
}
.toggle-switch {
position: relative;
height: 1.25rem;
width: 2rem;
}
.toggle-switch.active > .head {
background-color: #F7941E;
border-color: #F7841E;
transform: translateX(1rem);
}
.toggle-switch.active > .rail {
border: 0.125rem solid #F7941E;
background-color: white;
}
<div class='toggle-switch'>
<button class='head'></button>
<div class='rail'></div>
</div>

Bootstrap 4.1 floating labels

I've found on Google a doc example for Bootstrap 4.1 in which they feature floating labels: getbootstrap.com/docs/4.1/examples/floating-labels/
In that page, however, it is not explained how that can be achieved, and I can't find anything in the docs for v. 4.1. Floating labels are not even listed as a new feature in the ship list.
Does anyone know if floating labels are supported?
It says on the Bootstrap examples page that floating-labels are...
"Experiments - Examples that focus on future-friendly features or
techniques."
Like many of the other examples, there's an additional CSS file used in the example...
Using the floating-labels.css they work as expected in the supported browsers...
https://www.codeply.com/go/X9VbHqzD4B
Best way for me is using transform translate. It is smoother. I have added extra classes to prevent overwriting bootstraps original classes.
body{padding:75px}
.form-group.floating>label {
bottom: 34px;
left: 8px;
position: relative;
background-color: white;
padding: 0px 5px 0px 5px;
font-size: 1.1em;
transition: 0.1s;
pointer-events: none;
font-weight: 500 !important;
transform-origin: bottom left;
}
.form-control.floating:focus~label{
transform: translate(1px,-85%) scale(0.80);
opacity: .8;
color: #005ebf;
}
.form-control.floating:valid~label{
transform-origin: bottom left;
transform: translate(1px,-85%) scale(0.80);
opacity: .8;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"/>
<div class="form-group floating">
<input type="text" class="form-control floating" id="usr" required value="">
<label for="usr">Username</label>
</div>
Styles they ware using in that mentioned example site
:root {
--input-padding-x: .75rem;
--input-padding-y: .75rem;
}
html,
body {
height: 100%;
}
body {
display: -ms-flexbox;
display: -webkit-box;
display: flex;
-ms-flex-align: center;
-ms-flex-pack: center;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
padding-top: 40px;
padding-bottom: 40px;
background-color: #f5f5f5;
}
.form-signin {
width: 100%;
max-width: 420px;
padding: 15px;
margin: 0 auto;
}
.form-label-group {
position: relative;
margin-bottom: 1rem;
}
.form-label-group > input,
.form-label-group > label {
padding: var(--input-padding-y) var(--input-padding-x);
}
.form-label-group > label {
position: absolute;
top: 0;
left: 0;
display: block;
width: 100%;
margin-bottom: 0; /* Override default `<label>` margin */
line-height: 1.5;
color: #495057;
border: 1px solid transparent;
border-radius: .25rem;
transition: all .1s ease-in-out;
}
.form-label-group input::-webkit-input-placeholder {
color: transparent;
}
.form-label-group input:-ms-input-placeholder {
color: transparent;
}
.form-label-group input::-ms-input-placeholder {
color: transparent;
}
.form-label-group input::-moz-placeholder {
color: transparent;
}
.form-label-group input::placeholder {
color: transparent;
}
.form-label-group input:not(:placeholder-shown) {
padding-top: calc(var(--input-padding-y) + var(--input-padding-y) * (2 / 3));
padding-bottom: calc(var(--input-padding-y) / 3);
}
.form-label-group input:not(:placeholder-shown) ~ label {
padding-top: calc(var(--input-padding-y) / 3);
padding-bottom: calc(var(--input-padding-y) / 3);
font-size: 12px;
color: #777;
}
If you really want floating label, see this awesome Bootstrap 4 theme : http://djibe.github.io/material/docs/4.4/material/text-fields/
SCSS version below including support for textarea and excluding styles from IE11, which doesn't support :placeholder-shown.
:root {
--input-padding-x: .75rem;
--input-padding-y: .75rem;
}
.floating-label {
$placeholderColour: $middleGrey;
position: relative;
input, textarea, label {
padding: var(--input-padding-y) var(--input-padding-x);
}
label {
position: absolute;
top: 0;
left: 0;
display: block;
margin-bottom: 0;
line-height: 1.5;
color: $placeholderColour;
border: 1px solid transparent;
border-radius: .25rem;
transition: all .1s ease-in-out;
&:hover {
cursor: text;
}
}
input::-webkit-input-placeholder {
color: transparent;
}
input:-ms-input-placeholder {
color: transparent;
}
input::-ms-input-placeholder {
color: transparent;
}
input::-moz-placeholder {
color: transparent;
}
input::placeholder {
color: transparent;
}
textarea::-webkit-input-placeholder {
color: transparent;
}
textarea:-moz-placeholder {
color: transparent;
}
textarea::-moz-placeholder {
color: transparent;
}
textarea:-ms-input-placeholder {
color: transparent;
}
textarea::placeholder {
color: transparent;
}
input:not(:placeholder-shown),
textarea:not(:placeholder-shown) {
padding-top: calc(var(--input-padding-y) + var(--input-padding-y) * (2 / 3));
padding-bottom: calc(var(--input-padding-y) / 3);
}
input:not(:placeholder-shown) ~ label,
textarea:not(:placeholder-shown) ~ label {
padding-top: calc(var(--input-padding-y) / 3);
padding-bottom: calc(var(--input-padding-y) / 3);
font-size: 12px;
&:hover {
cursor: default;
}
}
#media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
label {
display: none;
}
textarea:-ms-input-placeholder, input:-ms-input-placeholder {
color: $placeholderColour;
}
textarea::-ms-input-placeholder, input::-ms-input-placeholder {
color: $placeholderColour;
}
}
}
I've created an input floating label for Bootstrap 4 & 5 (not the same look that Bootstrap provides): https://github.com/tkrotoff/bootstrap-floating-label
Here is the online demo: https://codesandbox.io/s/github/tkrotoff/bootstrap-floating-label/tree/codesandbox.io

Slow opening hamburger menu

I've been struggling with getting my hamburger menu to slowly open. It took me a long time to even create it. :) Can anyone tell me if this CSS code allows for having it gradually open?
http://codepen.io/kiddigit/pen/EKRgQz
#media only screen and (max-width: 700px) {
body {
background-color: #white;
}
img {max-width: 100%; padding-bottom: 10px;
}
h1 {
font-size: 30px;
}
.wrapper {
border: 0px;
padding: 1px;
background-color: white;
}
.content {
background-color: white;
border: none;
margin-left: 100px;
margin-right: 100px;
}
.menu-btn div{
float: left;
padding-right: 0px;
margin-top: 0em;
line-height: 1.2;
font-size: 18px;
font-weight: 200;
vertical-align: middle;
z-index: 99;
}
.menu-btn span {
display: block;
width: 25px;
height: 4px;
margin-bottom: 5px;
background: rgb(0,0,0);
z-index: 99;
}
.menu-btn span:last-of-type {
margin-bottom: 0;
}
.responsive-menu{
display: none;
overflow: hidden;
}
.responsive-menu ul {
width: 80px;
float: left;
margin-right: 0;
margin: 0;
}
.main-nav {
border: none;
}
a {
font-size: 10px;
color: white;
}
.responsive-menu li {
padding-left: 5px;
font-size: 10px;
line-height: 25px;
list-style-type: none;
background-color: black;
}
.expand {
display: block !important;
}
$( '.menu-btn' ).click(function(){
$('.responsive-menu').slideToggle('slow');
});
UPD: Smooth appearing of element when it changes display from none to block can't be achieved with CSS. JQuery has some functions for that, toggle() and slideToggle(). slideToggle looks better for dropdown as it changes height of element from 0 to its natural height. In brackets you can add animation speed, slow is equal to 600 milliseconds, time in milliseconds also can be used: $('.responsive-menu').slideToggle(500)

Resources