I'm trying to make a carousel (run snippet below) that:
scrolls left to right
has equal amount of space on both sides of the inside of the carousel
makes it to where the first and last inner elements are centered when the scrollX value is all the way to the left or the right.
The issue I'm facing is that neither margin NOR padding is working on the right side of the carousel and is only displaying on the left.
To see the exactly what I'm talking about, run the snippet below, scroll all the way to the right, and compare to when the carousel is scrolled all the way to the left (Day 7 should be in the middle of the div at the end):
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
h1 {
text-align: center;
margin-top: 10px;
margin-bottom: 20px;
}
nav {
display: flex;
align-items: center;
justify-content: center;
}
.carousel-wrapper {
position: relative;
}
/* Arrows (ignore them, they don't work yet) */
.carousel-wrapper::before,
.carousel-wrapper::after {
content: "";
border-top: 2px solid black;
border-right: 2px solid black;
position: absolute;
height: 10px;
width: 10px;
top: calc(50% - 5px);
cursor: pointer;
}
.carousel-wrapper::before {
transform: rotate(-135deg);
left: -20px;
}
.carousel-wrapper::after {
transform: rotate(45deg);
right: -20px;
}
/* Where overflow hidden and overflow-x: scroll is */
.carousel {
border: 1px solid black;
background-color: #21abde;
overflow: hidden;
overflow-x: scroll;
width: 300px;
}
/* PROBLEM AREA (where the margin and padding should be but isn't working */
.links {
display: flex;
transform: skew(-15deg);
flex-shrink: 0;
margin: 0 100px;
margin-right: 100px;
}
/* Anchors */
a {
display: flex;
justify-content: center;
align-items: center;
color: white;
background-color: #21abde;
width: 100px;
height: 50px;
flex-shrink: 0;
text-decoration: none;
}
a span {
transform: skew(15deg);
}
a:hover {
background-color: #044c66;
}
<body>
<h1>Dates</h1>
<nav class="dates">
<div class="carousel-wrapper">
<div class="carousel">
<div class="links">
<span>Day 1</span>
<span>Day 2</span>
<span>Day 3</span>
<span>Day 4</span>
<span>Day 5</span>
<span>Day 6</span>
<span>Day 7</span>
</div><!-- Padding / margin should be showing up here -->
</div>
</div>
</nav>
<script src="app.js"></script>
</body>
Now that you've seen the code snippet...
2 questions:
Why is overflow hidden NOT accounting the padding on the right side of the links div
How do you make it show up?
Thanks guys!
Add this to you .items class:
width: max-content;
padding: 0 100px;
Remove the margin and margin-right!
Related
I need to create a button with a close button and text.
The button might be horizontal, vertical and the content length is dynamic.
The content might be in EN, HE, JA, JO, ZH, etc.
To support JA, JO, ZH, etc, this article recommends to add a paragraph element with writing-mode: vertical-rl;
So eventually I have the HTML (which works great on chrome, but looks really bad on safari especially on safari mobile. the text is cut and out of the wrapper view):
body {
height: 100%;
width: 100%;
}
.wrapper.center-right {
cursor: pointer;
position: fixed;
height: auto;
margin: 0;
padding: 0;
display: flex;
z-index: 2147483647;
max-width: 200px;
background: red;
top: 50%;
display: flex;
flex-direction: column;
right: 0;
transform: translate(0, -50%);
transform-origin: right top;
}
.wrapper.center-right .text-button {
min-width: auto;
align-items: initial !important;
}
.wrapper.center-right .text-button .text{
writing-mode: vertical-rl;
padding: 0;
margin: 0;
max-height: 150px;
}
.text-button,
.close-btn {
border: solid 2px red;
outline: none;
box-sizing: border-box;
}
.text-button {
display: grid;
}
.text-button:focus,
.close-btn:focus {
color: blue;
outline: none;
border: blue solid 2px;
}
.text-button:focus .button-text {
color: blue;
}
<div class="wrapper center-right">
<button class="text-button">
<p class="text">my dynamic text making it a bit longer to reproduce the bug 国际化活动 نشاط التدويل 万维网联盟</p>
</button>
<button class="close-btn">
<img class="close-img" src="some-close-icon-path" />
</button>
</div>
I am building a navigation bar that has a lot of options and special sections.
I worked with Twitter Bootstrap, but it is difficult to develop.
The nav html tag has 3 sections grouped in 3 divs (left, center, right).
I am having difficulty in centring horizontally the text and logo of the company in left div, anchors with navigation items in the right div.
I need the height of navigation bar to be set in the CSS and not the calculate the height based of the child elements.
This is the html:
.navbar {
overflow: hidden; /* Clips from content if it is bigger than the parent element */
background-color: #333;
position: fixed; /* Position of the navbar is fixed */
top: 0;
width: 100%;
height: 50px;
}
.left-navbar {
float: left;
background: cadetblue;
width: 230px;
height: 100%;
text-align: center;
}
.right-navbar {
float: right;
background: maroon;
height: 100%;
/* float: right;
position: absolute;
top: 50%; right: 0%;
transform: translate(-50%,-50%);
background: gold;
padding: 1.5rem; */
}
.center-navbar {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%,-50%);
background: gold;
padding: 1rem;
}
.left-navbar strong {
color: red;
padding: 10px 10px;
display:inline-block;
text-align: center;
vertical-align: center;
}
.left-navbar img {
width: 32px;
height: 32px;
padding: 10px 10px;
}
.navbar a {
float: right; /* Orientation of the element in the parent element */
display: block; /* All over top left right bottom it is a block - element has block/padding all over the embedded element */
color: #f2f2f2;
text-align: center;
padding: 14px 16px; /* 14px top and bottom, 16px right and left */
text-decoration: none; /* Could be underline, overline, line-through */
font-size: 17px;
}
/* Apply only for anchors inside the navbar class */
.navbar a:hover {
background: #ddd;
color: black;
}
input[type="text"]{ padding: 5px 5px; line-height: 28px; }
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<nav class="navbar">
<div class="left-navbar">
<strong>Company</strong>
<img src="https://cdn0.iconfinder.com/data/icons/social-flat-rounded-rects/512/newsvine-512.png"></p>
</div>
<div class="center-navbar">
<input type="text" id="name" name="name" required height="45px;"
minlength="4" maxlength="40" size="40">
</div>
<div class="right-navbar">
Home
News
Contact
</div>
</nav>
Any working fiddle with best practices is ideal for me.
Thank you!
You can use flexbox to achieve this
.right-navbar, .left-navbar{
display: flex;
justify-content: center;
align-items: center;
}
Here you have a codepen, let me know if that help!
Give .left-navbar - horizontal and vertical centering with display:flex;
.left-navbar {
display: flex;
float: left;
background: cadetblue;
width: 230px;
height: 100%;
text-align: center;
justify-content: center;
align-items: center;
}
Also, how do you want the right part of the navbar?
Flex-box is what you'll want to use here. Add display: flex to the .navbar and then add flex-grow: 1; to the center piece. This essentially says 'make this element span the remaining space in the flex container. Also, your height: 100% were unnecessary, so I removed them.
.navbar {
overflow: hidden; /* Clips from content if it is bigger than the parent element */
background-color: #333;
position: fixed; /* Position of the navbar is fixed */
top: 0;
width: 100%;
height: 50px;
display: flex;
}
.left-navbar {
background: cadetblue;
width: 230px;
text-align: center;
}
.right-navbar {
background: maroon;
}
.center-navbar {
background: gold;
padding: 1rem;
flex-grow: 1;
}
input[type="text"]{
padding: 5px 5px;
line-height: 28px;
width: 100%;
box-sizing: border-box;
}
So I want to build a simple event box, to replace the default one in a calendar (react-big-calendar for reference, but I don't think it matters)
I would like to make it as responsive as possible, but I have started with a very static box, which corresponds to what I would like to see on a big screen.
Simple fiddle
.container {
width: 200px;
height: 200px;
background-color: #dddddd;
margin: 20px;
padding: 5px;
}
.event-slot-component {
width: 100%;
min-height: 30px;
position: relative;
background-color: #64a7DD;
border: 5px;
border-radius: 3px;
padding: 2px;
}
.event-slot-start-time {
font-size: 0.75em;
vertical-align: top;
position: absolute;
top: 0;
left: 0;
}
.event-slot-end-time {
font-size: 0.75em;
float: left;
vertical-align: bottom;
position: absolute;
bottom: 0;
left: 0;
}
.event-slot-label {
font-size: 1em;
top: 8px;
right: 5px;
position: absolute;
}
<div class="container">
<div class="event-slot-component">
<div class="event-slot-start-time">17h</div>
<div class="event-slot-end-time">21h</div>
<div class="event-slot-label">Occupied Slot</div>
</div>
</div>
My goal is to have a 'centered, eventually slightly to the right' label,
and two small indications on the left that correspond to the start and end of the event.
I have tried using flexbox, coming from other StackOverflow answers, and it does seem to be able to do that somehow, but I have not managed to display the three elements properly. Any insight on a clean solution to achieve this result?
The simplest with the existing markup is to use Flexbox with column direction on the 2 date values and then position the label absolute using transform
.container {
width: 200px;
height:200px;
background-color: #dddddd;
margin: 20px;
padding: 5px;
}
.event-slot-component {
width: 100%;
min-height: 30px;
position: relative;
background-color: #64a7DD;
border: 5px;
border-radius: 3px;
padding:2px;
display: flex;
flex-direction: column;
}
.event-slot-start-time,
.event-slot-end-time {
font-size: 0.75em;
flex-grow: 1; /* share the vertical space equal */
}
.event-slot-label {
position:absolute;
font-size: 1em;
top: 50%;
left: calc(50% + 10px); /* adjust px value for horiz. offset */
transform: translate(-50%,-50%); /* vert./hor. center the label */
}
<div class="container">
<div class="event-slot-component">
<div class="event-slot-start-time">17h</div>
<div class="event-slot-end-time">21h</div>
<div class="event-slot-label">Occupied Slot</div>
</div>
</div>
If you want a good responsive solution, use Flexbox all the way, here with a wrapper for the date's
.container {
width: 200px;
height:200px;
background-color: #dddddd;
margin: 20px;
padding: 5px;
}
.event-slot-component {
width: 100%;
min-height: 30px;
position: relative;
background-color: #64a7DD;
border: 5px;
border-radius: 3px;
padding:2px;
display: flex;
}
.event-slot-time {
display: flex;
flex-direction: column;
}
.event-slot-start-time,
.event-slot-end-time {
font-size: 0.75em;
flex-grow: 1; /* share the vertical space equal */
}
.event-slot-label {
flex-grow: 1; /* fill the remaining horizontal space */
font-size: 1em;
display: flex;
align-items: center; /* vertical center the label text */
justify-content: center; /* horizontal center the label text */
}
<div class="container">
<div class="event-slot-component">
<div class="event-slot-time">
<div class="event-slot-start-time">17h</div>
<div class="event-slot-end-time">21h</div>
</div>
<div class="event-slot-label">Occupied Slot</div>
</div>
</div>
You would need to nest your flexboxes. That's what's so wonderful about it!
To explain, what I did was created three wrappers.
One to hold the entire event.
One to hold your event times.
One to hold the status.
We used flex box to butt the event times and status-wrapper against each other. The event times only take up as much space as the text utilizes (plus a little padding). The status wrapper takes up 100% of its usable space.
Then status wrapper is set to flex box using the justify-content and align-items properties. This centers the status.
The status text container is used in the same way to center the status text itself.
.event-wrapper {
background-color: #eee;
display: flex;
}
.event-times-wrapper {
background-color: skyblue;
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.status-wrapper {
width:100%;
display: flex;
align-items:center;
justify-content: center;
}
.status-text {
height: 100%;
display:flex;
align-items: center;
padding-left: 1rem;
padding-right: 1rem;
background-color: tomato;
}
<article class="event-wrapper">
<div class="event-times-wrapper">
<p class="event-start">9:00a</p>
<p class="event-end">10:00a</p>
</div>
<div class="status-wrapper">
<div class="status-text">Busy</div>
</div>
</article>
As OP requested later, a sample without special containers.
.container {
background-color: #eee;
position: relative;
width: 100vw;
height:6rem;
}
.event-slot-component div {
font-family: sans-serif;
color: white;
background-color: skyblue;
height:3rem;
float:left;
padding-left: 1rem;
padding-right: 1rem;
width:10%;
display:flex;
align-items:center;
justify-content:center;
}
.event-slot-component div:nth-child(2) {
background-color:red;
position:absolute;
bottom:0;
left: 0;
}
.event-slot-component div:last-of-type {
margin-left:25%;
background-color: tomato;
float:left;
height: 6rem;
}
<div class="container">
<div class="event-slot-component">
<div class="event-slot-start-time">17h</div>
<div class="event-slot-end-time">21h</div>
<div class="event-slot-label">Occupied Slot</div>
</div>
</div>
Here is the outcome
What I want to achieve are
A gray circle surrounding the '<' with the letter in the center
It and 'untitled' aligns vertically to the center
However despite setting the width and height to the same size, the 'circle' still ends up in an oval shape.
The use of flex's align-items: center; also fails to achieve the alignment.
How can I fix the css? Here is a link to the sample code
html
<div class='flex-container'>
<div class='arrow-container'>
<a class='btn-icon' href='#'>
<span class='square-btn icon icon-back'></span>
</a>
</div>
<div class=title>
<a href='#'>Untitled
</a>
</div>
</div>
css
.flex-container {
display: flex;
align-items: center;
}
.icon {
font-size: 50px;
}
.icon-back::before {
content: '<';
}
.title {
margin-left: 5px;
font-size: 50px;
}
.square-btn {
height: 50px;
width: 50px;
}
.btn-icon {
padding: 5px;
border-radius: 50%;
background-color: gray;
text-decoration: none;
}
This seems to work. No changes to HTML.
.flex-container {
display: flex;
align-items: center;
}
.icon {
font-size: 50px;
}
.icon-back::before {
content: '<';
}
.title {
margin-left: 5px;
font-size: 50px;
}
.square-btn {
height: 50px;
width: 50px;
border-radius: 50%; /* new */
background-color: gray; /* new */
display: flex; /* new */
align-items: center; /* new; align arrow vertically */
justify-content: center; /* new; align arrow horizontally */
}
.btn-icon {
/* padding: 5px; <-- remove */
/* border-radius: 50%; <-- remove */
/* background-color: gray; <-- remove */
text-decoration: none;
}
<div class='flex-container'>
<div class='arrow-container'>
<a class='btn-icon' href='#'>
<span class='square-btn icon icon-back'></span>
</a>
</div>
<div class=title>
<a href='#'>Untitled
</a>
</div>
</div>
jsFiddle
This can be done with a single html element and pseude-elements. One neat advantage of making everything depend on the font-size is, that the icon scales proportionally with the font size of the link.
.link {
font-size: 50px;
margin-left: 1.1em;
}
.icon {
position: relative;
}
.icon-back::before {
content: '<';
position: absolute;
left: -.9em;
display: inline-block;
z-index: 2;
}
.icon-back::after {
content: '';
border-radius: 50%;
background-color: gray;
width: 1em;
height: 1em;
position: absolute;
top: 50%;
left: -1.1em;
/* Use translateX() and translateY()
if you care about old browsers */
transform: translate3d(0, -45%, 0);
}
<a class="link icon icon-back" href="#">Untitled</a>
Grouping classes makes things harder, also, use unicode in css content when it's not alpha-numerical text, try this:
<div class="flex-container">
<div class="arrow-container">
<a class="btn-icon" href="#">
<span class="icon-back"></span>
</a>
</div>
<div class="title">
<a href="#">Untitled
</a>
</div>
</div>
<style type="text/css">
.flex-container {
display: flex;
align-items: center;
}
.btn-icon {
font-size: 50px;
text-decoration: none;
}
.icon-back::before {
content: "\003c";
border-radius: 50%;
background-color: gray;
font-size: 40px;
height:40px;
width:40px;
vertical-align:middle;
display:inline-block;
margin-bottom:5px;
text-align:center;
}
.title {
margin-left: 5px;
font-size: 50px;
}
</style>
Here's the markup:
<nav id="the-nav">
<span id="backward"><i class="icon-backward"></i></span>
<div class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<span class="active-module"></span>
</a>
<ul class="dropdown-menu">
<li>
<img src="...">
</li>
<li>
<img src="...">
</li>
</ul>
</div>
<div class="wrapper">
<div class="modules">
<div class="module active">
<i class="icon-*"></i> <!-- a few bootstrap icons are used -->
<i class="icon-*"></i>
<i class="icon-*"></i>
</div>
<div class="module">
<i class="icon-*"></i>
<i class="icon-*"></i>
<i class="icon-*"></i>
<!-- More items here... -->
</div>
<!-- More modules here... -->
</div>
</div>
<span id="forward"><i class="icon-forward"></i></span>
</nav>
And here's the less/css:
#the-nav {
#itemDimension: 35px;
#dropdownWidth: 150px;
background: white;
bottom: 0;
left: 0;
position: fixed;
width: 100%;
/* Square mixin for items and navigator arrows. */
.square () {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
height: #itemDimension;
padding: 3px;
width: #itemDimension;
}
div, span { float: left; }
/* Module Dropdown */
.dropdown {
font-size: 12px;
white-space: nowrap;
width: #dropdownWidth;
/* Make dropdown drop "up". */
&.open > .dropdown-menu {
bottom: 100%;
top: inherit;
}
.active-module {
overflow: hidden;
text-overflow: ellipsis;
width: #dropdownWidth;
}
img {
height: 30px;
width: 30px;
}
}
.wrapper {
overflow: hidden;
position: relative;
white-space: nowrap;
/* Set width so that there is just enough room for the forward and back
* arrows. As a fallback, give it a percentage width. */
width: 88%;
width: -webkit-calc(100% ~'-' 2*#itemDimension+#dropdownWidth);
width: -moz-calc(100% ~'-' 2*#itemDimension+#dropdownWidth);
width: calc(100% ~'-' 2*#itemDimension+#dropdownWidth);
}
/* Forward/backward scoll buttons */
#forward, #backward {
.square;
padding: 7px 0 0 10px;
&:hover {
background: lightblue;
}
}
/* Module items */
.module > a {
.square;
float: left;
text-align: center;
i {
display: block !important;
font-size: 120%;
margin-top: 6px !important;
}
}
.module:not(.active) { display: none; }
}
The module shown (determined by the dropdown) is set using javascript.
I want this entire navbar to stay on one line. Currently, it works in Chrome, but not in Firefox. In Firefox, the contents of each module wrap to a new line so that the entire navbar spans multiple lines. I want this to all stay on one line.
I have a feeling there is some combination of display, float, and white-space that will get what I want, but I am not sure what that combination that is.
UPDATE Here is a codepen that shows exactly what I want. Again, this works on chrome, but not on firefox. http://codepen.io/anon/pen/Bolnd
Remove the float: left and add display: inline-block; to div, span:
div, span { display: inline-block; }
Recalculate the .wrapper width considering the paddings:
width: calc(100% ~'-' 2*#itemDimension+#dropdownWidth+2*#itemPadding+2*#directionalLeftPadding);
See the Codepen with the changes
Full CSS LESS code:
/* Bootstrap */
#import url('http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css');
/* FontAwesome */
#import url('http://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css');
#directionalLeftPadding: 10px;
#itemPadding: 3px;
#itemDimension: 35px;
#dropdownWidth: 150px;
.square () {
box-sizing: border-box;
height: #itemDimension;
padding: #itemPadding;
width: #itemDimension;
}
div, span { display: inline-block; }
nav {
bottom: 0;
position: fixed;
width: 100%;
}
/* Module Dropdown */
.dropdown {
float: left;
font-size: 12px;
white-space: nowrap;
width: #dropdownWidth;
/* Make dropdown drop "up". */
&.open > .dropdown-menu {
top: inherit;
bottom: 100%;
}
.active-module {
width: #dropdownWidth;
overflow: hidden;
text-overflow: ellipsis;
}
img {
width: 30px;
height: 30px;
}
}
.wrapper {
float: left;
overflow: hidden;
white-space: nowrap;
position: relative;
/* Set width so that there is just enough room
* for the forward and back arrows. As a
* fallback, give it a percentage width. */
width: 88%;
width: -webkit-calc(100% ~'-' 2*#itemDimension+#dropdownWidth+2*#itemPadding+2*#directionalLeftPadding);
width: -moz-calc(100% ~'-' 2*#itemDimension+#dropdownWidth+2*#itemPadding+2*#directionalLeftPadding);
width: calc(100% ~'-' 2*#itemDimension+#dropdownWidth+2*#itemPadding+2*#directionalLeftPadding);
}
/* Forward/backward scoll buttons */
#forward, #backward {
float: left;
.square;
padding: 7px 0 0 #directionalLeftPadding;
&:hover {
background: lightblue;
}
}
/* Module items */
.module > span {
.square;
text-align: center;
&:not(:last-child) { border-right: 1px solid black; }
i {
display: block !important;
font-size: 120%;
margin-top: 6px !important;
}
}
.module:not(.active) { display: none; }