How can I customize the arrow buttons below from swipers?
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
I did it crudely but it does not seem to be the right way because I get some margin on the right of the button.
<div class="swiper-button-next hide-for-small-only hide-for-medium-only" style="border: 1px solid red; background-color: yellow; padding: 30px; ></div>
The entire code:
.swiper-container {
width: 100%;
height: 450px;
}
.swiper-slide {
/* Center slide text vertically */
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
.swiper-slide {
font-size: 18px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.swiper-banner-slide {
-webkit-background-size: cover;
background-size: cover;
background-position: center;
}
.swiper-slide .title {
font-family: 'Bellefair', serif;
font-size: 41px;
line-height: 40px;
font-weight: 300;
}
.swiper-slide .subtitle {
font-size: 21px;
}
.swiper-slide .text {
font-size: 21px;
letter-spacing: 1px;
}
.slide-info-container {
color: #000;
}
.swiper-block {
padding: 40px 0 40px;
background: #eee;
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
font-size: 14px;
color: #000;
margin: 0;
/*padding: 0;*/
}
.swiper-block .swiper-container {
width: 100%;
height: 300px;
margin: 20px auto;
}
.swiper-block .swiper-slide {
text-align: center;
font-size: 18px;
background: #fff;
/* Center slide text vertically */
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
<!-- CDN -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<!-- Zurb - CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.1/css/foundation.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.1/js/foundation.min.js"></script>
<!-- Swiper - CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/css/swiper.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/css/swiper.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/js/swiper.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/js/swiper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/js/swiper.jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/js/swiper.jquery.min.js"></script>
<main>
<div class="row" id="banner">
<!-- Swiper -->
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide swiper-banner-slide" style="background-image: url('images/1.jpg')">
<!-- grid container -->
<div class="grid-container">
<div class="grid-x grid-padding-x">
<div class="small-12 medium-10 large-8 cell slide-info-container">
<h3 class="title">Aliquam dictum mattis velit 1</h3>
<div class="text">
<p>Nulla laoreet justo vitae porttitor porttitor. Suspendisse in sem justo. Integer laoreet magna nec elit suscipit, ac laoreet nibh euismod. </p>
</div>
More Details
</div>
</div>
</div>
<!-- grid container -->
</div>
<div class="swiper-slide swiper-banner-slide" style="background-image: url('images/2.jpg')">
<!-- grid container -->
<div class="grid-container">
<div class="grid-x grid-padding-x">
<div class="small-12 medium-10 large-8 cell slide-info-container">
<h3 class="title">Aliquam dictum mattis velit 2</h3>
<div class="text">
<p>Aliquam hendrerit lorem at elit facilisis rutrum. Ut at ullamcorper velit. Nulla ligula nisi, imperdiet ut lacinia nec, tincidunt ut libero. Aenean feugiat non eros quis feugiat.</p>
</div>
More Details
</div>
</div>
</div>
<!-- grid container -->
</div>
<div class="swiper-slide swiper-banner-slide" style="background-image: url('images/3.jpg')">
<!-- grid container -->
<div class="grid-container">
<div class="grid-x grid-padding-x">
<div class="small-12 medium-10 large-8 cell slide-info-container">
<h3 class="title">Aliquam dictum mattis velit 3</h3>
<div class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam dictum mattis velit, sit amet faucibus felis iaculis nec. </p>
</div>
More Details
</div>
</div>
</div>
<!-- grid container -->
</div>
<div class="swiper-slide swiper-banner-slide" style="background-image: url('images/4.jpg')">
<!-- grid container -->
<div class="grid-container">
<div class="grid-x grid-padding-x">
<div class="small-12 medium-10 large-8 cell slide-info-container">
<h3 class="title">Aliquam dictum mattis velit 4</h3>
<div class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam dictum mattis velit, sit amet faucibus felis iaculis nec. Nulla laoreet justo vitae porttitor porttitor. </p>
</div>
More Details
</div>
</div>
</div>
<!-- grid container -->
</div>
<div class="swiper-slide swiper-banner-slide" style="background-image: url('images/5.jpg')">
<!-- grid container -->
<div class="grid-container">
<div class="grid-x grid-padding-x">
<div class="small-12 medium-10 large-8 cell slide-info-container">
<h3 class="title">Aliquam dictum mattis velit 5</h3>
<div class="text">
<p>Nulla laoreet justo vitae porttitor porttitor. Suspendisse in sem justo.</p>
</div>
More Details
</div>
</div>
</div>
<!-- grid container -->
</div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination"></div>
<!-- Add Arrows -->
<div class="swiper-button-next hide-for-small-only hide-for-medium-only" style="border: 1px solid red; background-color: yellow; padding: 30px; ></div>
<div class=" swiper-button-prev hide-for-small-only hide-for-medium-only "></div>
</div>
<!-- Swiper -->
</div>
<!-- row block -->
<div class="row swiper-block ">
<div class="grid-container ">
<div class="grid-x grid-padding-x ">
<div class="small-12 cell ">
<!-- Swiper -->
<div class="swiper-container ">
<div class="swiper-wrapper ">
<div class="swiper-slide ">Slide 1</div>
<div class="swiper-slide ">Slide 2</div>
<div class="swiper-slide ">Slide 3</div>
<div class="swiper-slide ">Slide 4</div>
<div class="swiper-slide ">Slide 5</div>
<div class="swiper-slide ">Slide 6</div>
<div class="swiper-slide ">Slide 7</div>
<div class="swiper-slide ">Slide 8</div>
<div class="swiper-slide ">Slide 9</div>
<div class="swiper-slide ">Slide 10</div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination "></div>
</div>
</div>
</div>
</div>
</div>
</main>
<script>
$(function() {
$(document).foundation();
var swiper = new Swiper('#banner .swiper-container', {
pagination: '#banner .swiper-pagination',
slidesPerView: 1,
paginationClickable: true,
centeredSlides: true,
spaceBetween: 30,
loop: true,
keyboardControl: true,
nextButton: '#banner .swiper-button-next',
prevButton: '#banner .swiper-button-prev',
});
var swiper2 = new Swiper('.swiper-block .swiper-container', {
pagination: '.swiper-block .swiper-pagination',
slidesPerView: 5,
paginationClickable: true,
spaceBetween: 30,
freeMode: true,
keyboardControl: false,
});
});
</script>
I don't want the margin.
Any ideas?
EDIT:
How do I change the colour blue on the arrow to black?
.swiper-button-next,
.swiper-button-prev {
background-color: white;
background-color: rgba(255, 255, 255, 0.5);
right:10px;
padding: 30px;
color: #000 !important;
fill: black !important;
stroke: black !important;
}
Does not work of course!
Add this to style the prev / next arrows:
.swiper-button-prev {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%234c71ae'%2F%3E%3C%2Fsvg%3E") !important;
}
.swiper-button-next {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%234c71ae'%2F%3E%3C%2Fsvg%3E") !important;
}
Where "4c71ae" is the color you want to use in HEX.
:root {
--swiper-theme-color: #000;
}
Try this instead of !important to change color.
With the current version of SwiperJS (v.5.3.8) you can change the color of the arrows in css without any issues. Just define color.
.swiper-button-prev {
color: red;
}
.swiper-button-next {
color: #000;
}
Those who want to change the default arrows just set you custom SVG etc in the elements the HTML; mine is next & prev
<div class="swiper-button-next">Next</div>
<div class="swiper-button-prev">Prev</div>
And remove the default icons in CSS
.swiper-button-next::after, .swiper-button-prev::after {
content: "";
}
For anyone looking to change the color etc of various buttons etc for Swiper, be sure to inspect the CSS of what you are trying to change and see if the property you are trying to change is using a CSS variable.
In the case were a CSS variable has been used, you need to re-define it in order to change it.
Example for changing the color of the swiper next/prev buttons:
Underlying CSS:
.swiper-button-next, .swiper-button-prev {
position: absolute;
top: 50%;
width: calc(var(--swiper-navigation-size)/ 44 * 27);
height: var(--swiper-navigation-size);
margin-top: calc(0px - (var(--swiper-navigation-size)/ 2));
z-index: 10;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: var(--swiper-navigation-color,var(--swiper-theme-color));
}
Add this to the styles.css (or globals.css in NextJS)
:root {
--swiper-navigation-color: #E49A38;
}
"I don't want the margin. Any ideas?"
If the margin is really the margin, not the result of right property, try to overwrite default "swipers" styles using !important, like this:
.class {
margin: 0 !important;
}
Otherwise set right property to 0:
.class {
right: 0;
}
Or
.class {
right: 0 !important;
}
If it doesn't work without !important.
"How do I change the colour blue on the arrow to black?"
If you just want to make them black, you can simply use one of the built-in classes (swiper-button-black in your case) - thanks to this comment.
If you use JavaScript, you can also change --swiper-navigation-color inside the page/component instead of changing :root in the CSS file. I found it more convenient in React/Next.js. Just add this to your code.
document.documentElement.style.setProperty("--swiper-theme-color", "#000")
If you are going with this solution and you are building a React/Next.js app, remember to include the code from above in useEffect to load the document in the appropriate moment (more about it here).
useEffect(() => {
document.documentElement.style.setProperty("--swiper-theme-color", "#000")
}, [])
If you're using React, another approach apart from #Jakub’s is to pass a style prop to Swiper like this
<Swiper style={{"--swiper-navigation-color": "#FFF", "--swiper-pagination-color": "#FFF"}}>
.....
</Swiper>
If you're using Angular, you can simply use ::ng-deep to override the color.
For example :
::ng-deep .swiper-button-prev,
::ng-deep .swiper-button-next {
color: white;
}
.swiper-button-next::after, .swiper-button-prev::after{
content: "";
}
.swiper-button-next {
--swiper-navigation-color:white;
}
.swiper-button-prev {
--swiper-navigation-color:white;
}
If you just want to make them white or black you can use the built-in classes.
<div class="swiper-button-prev swiper-button-white"></div>
or
<div class="swiper-button-next swiper-button-black"></div>
Very simple
.main__swiper_left {
background-image: url("../img_2/main__swiper_left.png");
width: 58px;
height: 58px;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
.main__swiper_left::after {
display: none;
}
Source
For the color, edit the swiper-bundle.min.css on line 13, change the :root attribute to this:
:root {
--swiper-theme-color: #FFFFFF;
}
For those who want to replace default arrows with custom SVG icon. I'm using Swiper version 8.3.2.
Here is a demo example project.
Place <img> tag into both elements.
<!-- Navigation arrows -->
<div class="swiper-button-prev">
<img src="#/assets/icons/svg/right-arrow.svg" />
</div>
<div class="swiper-button-next">
<img src="#/assets/icons/svg/right-arrow.svg" />
</div>
Then, remove the default icons in CSS.
.swiper-button-prev::after,
.swiper-button-next::after {
display: none;
}
.swiper-button-prev img {
transform: rotate(180deg);
}
This solution worked for me:
// use the `useState` hook instead of `useRef`
const [prevEl, setPrevEl] = useState<HTMLElement | null>(null)
const [nextEl, setPrevEl] = useState<HTMLElement | null>(null)
<Swiper navigation={{ prevEl, nextEl }}>
// some slides
</Swiper>
<div ref={(node) => setPrevEl(node)}>prev</div>
<div ref={(node) => setNextEl(node)}>next</div>
.swiper.swiper-button-next {color: black; --swiper-navigation-size: 30px;}
.swiper.swiper-button-prev{color: black; --swiper-navigation-size: 30px;}
Try this one! to Increase and Decrease Size and Change Color.
Don't forget to use !important after the color property.
There are many ways to customize these arrows. You just need to specify your proper parameters in the :root of your CSS file.
:root {
--swiper-navigation-size: 16px; /* To edit the size of the arrows */
--swiper-navigation-color: #000; /* To edit the color of the arrows */
}
.swiper-button-prev {
color: green !important;
}
.swiper-button-next {
color: green !important;
}
If you want to change the color, you can simply do the following and it will overwrite the current color to white... Hope this will be useful!
Note: You can specify any color you want to change! Thanks
.swiper-button-prev,.swiper-button-next{
color:white !important;
}
This worked for me.
.swiper-button-prev {
color: red !important;
}
.swiper-button-next {
color: red !important;
}
Related
I have this gallery of images and I want on hover to zoom the image. I have shown below two images the first one is without hover effect and the second one is when image is hovered. This should be applied on every image. I also show you the code that I used to create the gallery.
HTML
<div class="tab-content">
<div class="tab-pane active" id="all">
<div class="row">
<div class="col-xl-6 col-lg-6 ">
<div class="first-img">
<img src="img/image_1.png" alt="">
<div class="text">
<h3>Mixed Gin Drinks</h3>
<p>Sit amet commodo nulla facilisi</p>
</div>
</div>
<div class="second-img">
<img src="img/image_3.png" alt="">
<div class="text">
<h3>Gin Tonic</h3>
<p>Sit amet commodo nulla facilisi</p>
</div>
</div>
</div>
<div class="col-xl-6 col-lg-6 second-col">
<div class="third-img">
<img src="img/image2.png" alt="">
<div class="text">
<h3>Gin on a Bar </h3>
<p>Sit amet commodo nulla facilisi</p>
</div>
</div>
<div class="fourth-img">
<img src="img/image_4.png" alt="">
<div class="text">
<h3>Gin Tonic 2</h3>
<p>Sit amet commodo nulla facilisi</p>
</div>
</div>
</div>
</div>
</div>
</div>
CSS
main .gallery .tab-content .tab-pane .first-img,.second-img,.third-img,.fourth-img{
position: relative;
margin-bottom: 15%;
}
main .gallery .tab-content .tab-pane .second-col{
margin-top:5%
}
main .gallery .tab-content .tab-pane .text{
position: absolute;
left: 50px;
bottom: -60px;
}
main .gallery .tab-content .tab-pane .text h3{
font-size: 40px;
line-height: 48px;
letter-spacing: 0px;
font-weight: bold;
margin-bottom: 0;
}
main .gallery .tab-content .tab-pane .text p{
font-size: 16px;
opacity: 0.5;
}
main .gallery .tab-content .tab-pane img{
width: 100%;
}
If you want to try that with CSS, you can try the "Transform" Property + scale.
choose your selector, in below "img" tag is taken, you can select yours:
img:hover {
transform: scale(2,2);
}
You can achieve this by selecting the "img" tag in the CSS as shown below,
img{
transition: 0.5s all ease-in-out; /*Animation for smooth transformation of images*/
}
Now, to add the zoom effect on hover
img:hover{
transform: scale(1.5); /*150% zoom*/
}
Here's my css code and HTML. Whenever a line in my carousel-caption becomes too long it falls off the image. When I minimize the window, however, the caption eventually moves into the image creating the effect I really want. Wondering how I can contain it to the image? Thanks for the help - because I am relatively new to CSS/BOOTSTRAP styling.
* {
margin: 0;
padding: 0;
}
a {
background-color: transparent !important;
color: white;
}
img {
max-width: 100%;
max-height: 80vh;
margin: auto;
}
.carousel-caption {
padding: 30px;
background-color:transparent !important;
position: absolute;
}
.picsum-img-wrapper {
padding-bottom: 20px;
padding-top: 20px;
background-color: #8E9AAF ;
color: white;
font-size: 20px;
font-family: orpheuspro, serif;
font-style: normal;
font-weight: 600 !important;
display: grid;
height: 100%;
}
h3 {
background-color: transparent !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ngb-carousel [showNavigationArrows]="true"
[showNavigationIndicators]="true"
interval="12000"
[keyboard]="true"
[pauseOnHover]="true"
[wrap]="true"
[activeId]="'secondSlide'"
[interval]="3000" [pauseOnHover]="pauseOnHover" (slide)="onSlide($event)">
<ng-template ngbSlide>
<div class="picsum-img-wrapper">
<img src="../../assets/img/actual.png" alt="Angular Carousel 1">
<div class="carousel-caption">
<h3>Title Goes Here</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.. To read on click <a routerLink="/blog/1">here</a></p>
</div>
</div>
</ng-template>
<ng-template ngbSlide>
<div class="picsum-img-wrapper">
<img src="../../assets/img/image0.jpeg" alt="Angular Carousel 2">
<div class="carousel-caption">
<h3>Title Goes Here</h3>
<p>Consectetur tortor volutpat pretium... To read on click <a routerLink="/blog/2">here</a></p>
</div>
</div>
</ng-template>
</ngb-carousel>
Assume I have a small component in a web application that represents an expander control, i.e. a header text, an icon to expand / collapse and some content.
A very simple React implementation (pseudo code) could look like this:
const Expander = ({children, title, onExpandToggle, isExpanded}) => (
<div>
<div><span>{title}</span><img src={...} onClick={onExpandToggle} /></div>
{isExpanded && children}
</div>
);
This implementation shows the icon after the title, so the position of the icon is determined by the length of the title.
It could look something like this:
Now assume that there are multiple like this below each other. It becomes messy:
To make this cleaner, all icons should have the same padding from left. The padding should not be fixed but dynamic, so that the longest title determines the position of all icons:
Assuming that I want to keep the expander in its own component, is there a CSS way to achieve my goal?
So far, I haven't tried anything as I don't have a starting point. In WPF I would have used something like SharedSizeGroup, but this doesn't exist for CSS.
Assuming you'll have a container to your component, you can set display: flex to the inner container and align-self: flex-end to your image.
Then wrap your component/s with a div that has display: inline-block which takes the width of the biggest element inside.
Here's an example:
.container{
display: inline-block;
padding: 3px;
}
.item{
display: flex;
flex-direction: row;
justify-content: space-between;
}
.item .plus{
width: 15px;
height: 15px;
background-image: url("https://cdn1.iconfinder.com/data/icons/mix-color-3/502/Untitled-43-512.png");
background-size: cover;
background-repeat: no-repeat;
align-self: flex-end;
margin-left: 10px;
}
<div class="container">
<div class="item">
<div>Synonyms</div>
<div class="plus"></div>
</div>
<div class="item">
<div>Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div>Term</div>
<div class="plus"></div>
</div>
</div>
Affecting all the instances without a shared container or fixed width and with CSS alone, is not possible, since there is no way to access a parent element with CSS. Therefore, If you'll have an inner instance (the biggest one) it won't be able to apply it's width to its own parent or any ancestor and it's other children.
If you're after a solution that will set all the instances in the page with the same size without them sharing a container you can achieve it with JS.
Calculate the width of each instance, save the biggest, then set this width for the rest of the instances. In this example I'm also highlighting the biggest item. The items are all around the page and can be inside various divs and displays or without any container.
var biggestWidth = 0;
var biggestItem;
function setWidth() {
$(".item").each(function() {
var currentWidth = $(this).width();
if (currentWidth > biggestWidth) {
biggestWidth = Math.ceil(currentWidth);
biggestItem = $(this);
}
});
$(".item").width(biggestWidth);
biggestItem.addClass("biggest");
}
$(setWidth());
section {
width: 40%;
float: left;
border: 1px solid black;
border-radius: 3px;
margin: 10px;
padding: 10px;
}
.s1 {
background-color: #e5e5e5;
display: table;
}
.item {
display: inline-block;
clear: both;
float: left;
}
.txt {
float: left;
display: inline-block;
}
.plus {
width: 15px;
height: 15px;
background-image: url("https://cdn1.iconfinder.com/data/icons/mix-color-3/502/Untitled-43-512.png");
background-size: cover;
margin-left: 10px;
float: right;
}
.shift{
margin-left: 30%;
}
.clear{
clear: both;
}
.biggest{
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="s1">
<div class="item">
<div class="txt">Synonyms</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Term</div>
<div class="plus"></div>
</div>
</section>
<section>
<div class="item">
<div class="txt">Synonyms</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Term</div>
<div class="plus"></div>
</div>
</section>
<section>
<div class="item">
<div class="txt">Synonyms - Long</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Term</div>
<div class="plus"></div>
</div>
</section>
<div class="item">
<div class="txt">Synonyms</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Term</div>
<div class="plus"></div>
</div>
<div class="clear"></div>
<div class="shift">
<div class="item">
<div class="txt">Synonyms</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">Concept</div>
<div class="plus"></div>
</div>
<div class="item">
<div class="txt">The bigget item is here</div>
<div class="plus"></div>
</div>
</div>
You can also try using the css display property "table-row" and "table-cell".
style:
.trow {
display: table-row;
}
.tcell
{
display: table-cell;
padding: 2px;
}
You can design your component like following.
const Expander = ({children, title, onExpandToggle, isExpanded}) => (
<div className="trow">
<div className="tcell">{title}</div>
<div className="tcell"><img src={...} onClick={onExpandToggle} /></div>
{isExpanded && children}
</div>
);
Example
.trow {
display: table-row;
}
.tcell
{
display: table-cell;
padding: 2px;
}
<div>
<div class="trow">
<div class="tcell">Synonyms</div>
<div class="tcell">X</div>
</div>
<div class="trow">
<div class="tcell">Concept</div>
<div class="tcell">X</div>
</div>
<div class="trow">
<div class="tcell">Term</div>
<div class="tcell">X</div>
</div>
</div>
I think that strictly speaking, with all the restrictions you've laid out, the answer is "no, it's not possible".
But since I believe that you need, at any rate, to group those expanders somehow (alternative being that every expander on the page would be horizontally aligned, to which no complete CSS solution exists either), you can simply count on the CSS box model.
<div style="background-color: #efffef; display: inline-block;">
<div style="position: relative; padding-right: 36px;">
<span>Title 1</span>
<span style="position: absolute; right: 0; top: 0;">[x]</span>
</div>
<div style="position: relative; padding-right: 36px;">
<span>Long title 2</span>
<span style="position: absolute; right: 0; top: 0;">[x]</span>
</div>
<div style="position: relative; padding-right: 36px;">
<span>Title 3, at your service</span>
<span style="position: absolute; right: 0; top: 0;">[x]</span>
</div>
</div>
I personally would do it with classic <table>. Its easy, semantically correct, and it will be done in 3 minutes. But we could do it also with display:inline-block and float:right, or with <table>-imitation using display:table, display:table-row and display:table-cell. In my opinion display: flex is relative new and not overall cross-browser compatible (for example IE10, IE11 and others). Because of all it I would like to provide you 3 solutions.
Solution with display:inline-block and float:right
With display:inline-block the size is always aligned on the content.
.container,
.item div,
.item b{display:inline-block}
.item b
{
float:right;
width:16px;
height:16px;
margin-left:5px;
cursor:pointer;
background:url("https://i.stack.imgur.com/bKWrw.png")
}
<div class="container">
<div class="item">
<div>Synonyms</div>
<b></b>
</div>
<div class="item">
<div>Concept</div>
<b></b>
</div>
<div class="item">
<div>Term</div>
<b></b>
</div>
</div>
<br style="clear:both">
Solution with <table>-imitation
.container{display:table}
.item{display:table-row}
.item div{display:table-cell; vertical-align:top}
.item b
{
display:inline-block;
width:16px;
height:16px;
cursor:pointer;
margin-left:5px;
background:url("https://i.stack.imgur.com/bKWrw.png")
}
<div class="container">
<div class="item">
<div>Synonyms</div>
<div><b></b></div>
</div>
<div class="item">
<div>Concept</div>
<div><b></b></div>
</div>
<div class="item">
<div>Term</div>
<div><b></b></div>
</div>
</div>
Solution with classic <table> (my favorite)
.menu td{vertical-align:top}
.menu td b
{
display:inline-block;
width:16px;
height:16px;
cursor:pointer;
margin-left:5px;
background:url("https://i.stack.imgur.com/bKWrw.png")
}
<table class="menu" cellpadding="0" cellspacing="0">
<tr>
<td>Synonyms</td>
<td><b></b></td>
</tr>
<tr>
<td>Concept</td>
<td><b></b></td>
</tr>
<tr>
<td>Term</td>
<td><b></b></td>
</tr>
</table>
The simplest example I can think of, based on your code snippet, would be something like:
const containerStyle = {
width: `[whatever width you need for the container]`,
display: `flex`,
flexDirection: `column`
}
const itemStyle = {
width: `100%`,
display: `flex`,
flexDirection: `row`,
justifyContent: `space-between`
}
const Expander = ({children, title, onExpandToggle, isExpanded}) => (
<div style={containerStyle}>
<div style={itemStyle}>
<span>{title}</span>
<img src={...} onClick={onExpandToggle} />
</div>
{isExpanded && children}
</div>
);
const Expander = (children, title, onExpandToggle, isExpanded) => (
<div>
{title}
<img src={...} style={{marginLeft : '5px',float : 'right'}} onClick={onExpandToggle}/>
</div>
<div style={{width : '0px',overflowX : 'visible'}}>
{isExpanded && <div>
{children}
</div>}
</div>
);
And put it in:
<div style={{display : 'inline-block'}}>
<Expander />
<Expander />
</div>
In CSS it is not possible for different elements of a page to "know" each other. The closest thing you can get is to use display flex and/or grid. This way the direct parent can control the way its children will display, kind of similar to React.
The main difference between flex and grid is that flex is 1 axis and grid 2 axis.
Working example using grid and flex:
<div class="container">
<div class="summary"><span class="text">Synonyms</span> <span class="icon">+</span></div>
<div class="details">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet officiis sequi perspiciatis sapiente iure minus laudantium! Quidem iure consectetur quod odit iusto, labore sunt quae, enim nesciunt officiis, quia ad.</p>
</div>
<div class="summary"><span class="text">Concept</span> <span class="icon">+</span></div>
<div class="details">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet officiis sequi perspiciatis sapiente iure minus laudantium! Quidem iure consectetur quod odit iusto, labore sunt quae, enim nesciunt officiis, quia ad.</p>
</div>
<div class="summary"><span class="text">Terms</span> <span class="icon">+</span></div>
<div class="details">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet officiis sequi perspiciatis sapiente iure minus laudantium! Quidem iure consectetur quod odit iusto, labore sunt quae, enim nesciunt officiis, quia ad.</p>
</div>
</div>
<style>
.container {
display: grid;
/* summary's width needs to be relative to the longest text
and details needs to span the whole grid */
grid-template-columns: auto auto;
}
.summary {
grid-column: 1 / 2; /* start at the beginning of 1st column and end at the beginning of the 2nd column */
display: flex; /* create horizontal layout */
justify-content: space-between; /* place the available space between the children */
}
.details {
grid-column: 1 / 3; /* start at the beginning of 1st column and end at the end of the 2nd column */
}
</style>
As you can see, it is very readable and requires very little markup.
With flex and grid you need to think on 2 levels parent > child. This means you need to change your React component accordingly:
const Expander = ({children, title, onExpandToggle, isExpanded}) => (
<>
<div class="summary" onClick={onExpandToggle}><span class="title">{title}</span> <span class="icon">+</span></div>
{isExpanded && (
<div class="details">
{children}
</div>
)}
</>
);
Here I removed the wrapper div in order to use a Fragment to ensure .summary and .details are direct children of a .container. Note that I also moved the onClick on the whole title for UX reasons.
CSS Grid is very useful and flexible, it is worth learning it. The browser support is recent but quite good, just make sure you use autoprefixer.
You can also use tricks using display: inline-block; whose size is based on its children but will involve workarounds when one of the children needs to overflow (like in your case). So I don't recommend it. I would also advise against using Javascript.
Don't hesitate to tell me what you think about this answer.
It is possible.
1. Flex-box + Absolution:
if you don't mind to use absolute positioned container, you can do it in this way
.container {
display: inline-flex;
flex-direction: column;
align-items: stretch;
width: auto;
}
.item {
margin: 5px 0;
padding: 5px;
border: 1px solid black;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
}
.header img {
width: 8px;
height: 8px;
margin-left: 20px;
cursor: pointer;
}
<div class="container">
<div class="item">
<div class="header">
<span>Synonyms</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
<div class="item">
<div class="header">
<span>Concept</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
<div class="item">
<div class="header">
<span>Term</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
</div>
The main problem here is that you don't know the height of the container so it might influence other content.
2. Inline Flex-box:
if the container position is critical for you, you can use inline-flex
.wrapper {
margin: 20px 10px;
}
.container {
display: inline-flex;
flex-direction: column;
align-items: stretch;
width: auto;
}
.item {
margin: 5px 0;
padding: 5px;
border: 1px solid black;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
}
.header img {
width: 8px;
height: 8px;
margin-left: 20px;
cursor: pointer;
}
Some content above the container...
<div class="wrapper">
<div class="container">
<div class="item">
<div class="header">
<span>Synonyms</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
<div class="item">
<div class="header">
<span>Concept</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
<div class="item">
<div class="header">
<span>Term</span>
<img src="https://image.flaticon.com/icons/png/512/61/61155.png" />
</div>
</div>
</div>
</div>
Some content below the container...
i have a beautiful little landing page with big pictures and small boxes with headings in it.
if you hover over the headings, the box around it should slide out (getting more width but shouldn't push the picture away, instead it should be above the picture) the picture next to it and shows some text there. this is all done in a flexbox-bootstrap layout.
will position: absolute, z-index and some left or right stuff do this trick as well even in a flexbox-content? or do i have to use some jscript/jQuery stuff?
here's my bootply: http://www.bootply.com/d2liwNZnCH
and the code for the greater good:
<main class="container">
<div class="row row-flex row-flex-wrap">
<div class="col-md-3 bgb fw">
<div class="contentbox flex-col">
<h2>example</h2>
</div>
</div>
<div class="col-md-3">
<div class="imagecontainer">
<img src="http://placehold.it/365x365" alt="Beispielinhalt" class="img-responsive">
</div>
</div>
<div class="col-md-3">
<div class="imagecontainer">
<img src="http://placehold.it/365x365" alt="Beispielinhalt" class="img-responsive">
</div>
</div>
<div class="col-md-3 bgr fw">
<div class="contentbox flex-col">
<h2>example</h2>
</div>
</div>
</div>
<div class="row row-flex row-flex-wrap">
<div class="col-md-8">
<div class="imagecontainer">
<img src="http://placehold.it/1265x365" alt="Beispielinhalt" class="img-responsive">
</div>
</div>
<div class="col-md-4 bgp fw">
<div class="contentbox flex-col">
<h2>example</h2>
</div>
</div>
</div>
<div class="row row-flex row-flex-wrap">
<div class="col-md-5 bgg fw">
<div class="contentbox flex-col">
<h2>example</h2>
</div>
</div>
<div class="col-md-7">
<div class="imagecontainer">
<img src="http://placehold.it/765x365" alt="Beispielinhalt" class="img-responsive">
</div>
</div>
</div>
</main> <!-- Maincontent -->
css:
.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
margin: 0;
padding: 0;
}
.row-flex, .row-flex > div[class*='col-'] {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
flex:1 1 auto;
}
.row-flex-wrap {
-webkit-flex-flow: row wrap;
align-content: flex-start;
flex:0;
}
.row-flex > div[class*='col-'], .container-flex > div[class*='col-'] {
margin:-.2px; /* hack adjust for wrapping */
}
.container-flex > div[class*='col-'] div,.row-flex > div[class*='col-'] div {
width:100%;
}
.flex-col {
display: flex !important;
display: -webkit-flex !important;
flex: 1 100%;
flex-flow: column nowrap;
align-items: center;
justify-content: center;
}
.flex-grow {
display: flex;
-webkit-flex: 2;
flex: 2;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0px;
word-break: break-word;
}
.contentbox {
padding: 15px 30px 15px 30px;
text-align: center;
display: block;
}
.contentbox h2 {
font-variant: small-caps;
}
.imagecontainer {
display: block;
}
did it with a second ".contentbox"-div and some helper classes and jQuery click event and i chosed to fade the readmore-text in the contentbox itself above the centered heading.
html:
<div class="col-lg-3 col-sm-6 col-xs-12 fw">
<div class="contentbox readmore bgr flex-col">
<h2>example</h2>
</div>
<div class="contentbox expand bgr flex-col">
<span aria-hidden="true" class="pull-right closebox">×</span>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata.</p>
<p>read more</p>
</div>
</div>
css:
.contentbox {
padding: 15px 30px 15px 30px;
text-align: center;
display: block;
height: auto;
min-height: 160px; /* Only for my layout */
}
.readmore {
cursor: pointer; /* So your complete box seems clickable */
}
.expand {
position: absolute;
top: 0; /* You can switch these values to whatever values wished */
left: 0; /* It will then slide from the direction you chose */
right: 0; /* but remember to put the chosen direction to 0 again on .expanded */
bottom: 0; /* for me, the fadeeffect was the most elegant way */
font-size: 15px;
opacity: 0;
visibility: hidden;
transition: all .75s ease-in-out;
}
.expanded {
top: 0;
opacity: 1;
visibility: visible;
cursor: default;
transition: all .75s ease-in-out;
}
.closebox {
font-size: 24px;
position: absolute;
right: 10px;
top: 0px;
cursor: pointer;
}
js within document ready:
$(".readmore").click(function(){
$(this).next(".expand").addClass("expanded");
});
$(".closebox").click(function(){
$(this).parent(".expanded").removeClass("expanded");
});
I am new to web development and currently building a site for a friend that is being modeled after this one: http://fulton-demo.squarespace.com/
While I have most of the elements into code and styled, I cannot figure out how to get the images and content to fill 100% of the width AND resize when the browser window is resized. Like, take the first image on the link I provided for example...I would like it to look like this, meaning to not have any margins on either side and fill the browser window....and I can get it to do that, but it never shows 100% of the image and when I resize the window, nothing moves. Does that make sense?
I know this is probably a very elementary question, but I would love some insight on this. I can post any and all code if necessary. Thanks in advance guys!
EDIT: Here is my code:
HTML:
<!doctype html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css"/>
<link rel="stylesheet" type="text/css" href="slick/slick.css"/>
<meta charset="utf-8">
</head>
<body>
<main id="mainContent" role="main">
<article role="article">
<section>
<header>
<div class="container">
<div class="single-item-rtl" dir="rtl">
<div><img src="img/6.jpg" height="600px" width="1400px" align= center/></div>
<div><img src="img/6.jpg"height="600px" width="1400px" align= center/></div>
<div><img src="img/6.JPG" height="600px" width="1400px" align= center/></div>
<div><img src="img/6.jpg" height="600px" width="1400px" align= center/></div>
</div>
<div id=logo><img src="img/SJ_WHT.png" height="170px" width="220x" align=center</div>
<div id=text-top-carousel>
<h1>a better way to book creative spaces</h1>
</div>
</div>
</header>
</section>
<section id="info">
<div class="info">
<div class="icon"></div>
<h2>unique spaces <br> that inspire</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod temor incididunt ut labore et dolore magna aliqua</p>
</div>
<div class="info">
<div class="icon"></div>
<h2>hassle free <br> booking</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod temor incididunt ut labore et dolore magna aliqua</p>
</div>
<div class="info">
<div class="icon"></div>
<h2>share your <br>creative space</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod temor incididunt ut labore et dolore magna aliqua</p>
</div>
<div class="motto">
<h1>unleash your creativity</h1>
<p>We focus on your artistic expression at Studio Junkey. We believe that your creative process is limited when the necessary resources are not available to execute your vision. <br></nr> We want to ensure that you find the studio space that has the tools you need to express yourself and your vision</p>
</div>
</section>
<section id="contactForm">
<div class="form">
<h3>Want to list a studio space?</h3>
<p>We are looking for more studios.
Send us your information so we can connect.</p>
</div>
</section>
<footer role="footer">
</footer>
</article>
</main>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"> </script>
<script type="text/javascript" src="slick/slick.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.single-item-rtl').slick({
rtl: true,
autoplay: true,
autoplaySpeed: 3000,
});
});
</script>
</body>
</html>
CSS:
#font-face {
font-family: "Brandon Grotesque";
src: url("fonts/Brandon_Grotesque/Brandon_reg.otf") format("opentype");
}
html, body {
height: 100%;
width: 100%;;
padding:0;
margin: 0;
}
body {
font-family:"Brandon Grotesque";
}
#mainContent {
background: white;
width:1500px;
}
.container {
width: 100%;
max-width: 1400px;
height:600px;
text-align:center;
margin: 0 auto;
}
#logo {
position:relative;
top:-595px;
left:0em;
}
#text-top-carousel h1 {
position:relative;
top:-15px;
left:0em;
color:white;
font-size:55px;
padding: 10px;
}
#info {
margin: 0px;
clear:both;
}
.info {
width:466px;
height:400;
padding:10px;
background:white;
text-align: center;
color:#333333;
margin: 0px;
float:left;
clear: none;
}
.info.icon {
background:black;
border:1px solid white;
width:100px;
height:100px;
padding:10px;
margin-bottom: 25px;
}
.info h2 {
padding:300px 48px 10px 48px;
font-size: 45px;
margin-bottom: 0px;
margin-top: 0px;
line-height: 1em;
}
.info p {
padding:15px 50px 45px 50px;
margin: 0px;
font-size: 20px;
}
.motto {
background-image:url("img/6.jpg");
text-align: center;
color: white;
clear: both;
width:1400px;
margin:0 auto;
margin-bottom:0px;
height: 600px;
}
.motto h1 {
font-size: 60px;
padding-top: 90px;
margin-bottom: 20px;
}
.motto p {
font-size: 30px;
padding: 15px 100px 90px 100px;
}
#contactForm {
background: #EDEFED;
margin-top:0px;
width: 1400px;
height: 600px;
margin: 0 auto;
clear: both;
}
.form {
text-align: center;
margin: 0;
width:50%;
height:500px;
color:#333333;
clear:both;
}
.form h3 {
margin: 0;
font-size: 40px;
padding: 115px 185px 50px 185px;
}
EDIT 2: THANK YOU for all the help thus far everyone!....For those following along in the comments, the issue that I'm having now can be shown by this screenshot. The image carousel seems to be filling the left side completely fine, but the right side still isn't being filled at all, there's still some space between the right edge of the img carousel and the browser window when I scroll to the right.
Try adding this to your CSS..
.single-item-rtl img {
width: 100%;
height: auto;
max-height: 600px;
margin: auto;
}
Also remove the height width and align from the image tag or they'll override the CSS.
Slick tries to add arrows to the left and right side of the slider which is what is causing the issue. Since we're taking up 100% of the screen they have no place to go.
$('.single-item-rtl').slick({
rtl: true,
arrows: false
});
Edit:
Remove the width from #mainContent to make .container's with take up 100% of the screen.
Enclosing your content inside another element is helpful.
Note that you have to separate between enclosing elements required for your script to work, and those used to enchance your layout.
Also my solution implies you will ever be able to specify your image width in percent only. You can also add maximum and minimum properties.
.outer {
width: 5cm; // arbitrary
}
.full-width {
width: 100%;
}
.full-width img {
width: 15%;
max-width: 2cm;
min-width: 5mm;
}
<div class="outer">
<div class="full-width">
<img src="http://cdn.sstatic.net/stackoverflow/img/favicon.ico"/>
</div>
</div>
Use Percentage widths!!!!
Something simple like this would do:
.myImageClass{
width: 50%;
/*by not setting height, it will auto scale*/
}
DEMO:
html,body{
margin:0;
padding:0;
}
.myFullImg{
width:100%;
}
.myHalfImage{
width:50%;
}
<img class="myFullImg" src="http://placekitten.com/g/200/200" alt=""/>
<img class="myHalfImage" src="http://placekitten.com/g/200/400" alt=""/>